// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package compute provides access to the Compute Engine API.
//
// For product documentation, see: https://developers.google.com/compute/docs/reference/latest/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/compute/v1"
//   ...
//   ctx := context.Background()
//   computeService, err := compute.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   computeService, err := compute.NewService(ctx, option.WithScopes(compute.DevstorageReadWriteScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   computeService, err := compute.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   computeService, err := compute.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package compute // import "google.golang.org/api/compute/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "compute:v1"
const apiName = "compute"
const apiVersion = "v1"
const basePath = "https://compute.googleapis.com/compute/v1/projects/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"

	// View and manage your Google Compute Engine resources
	ComputeScope = "https://www.googleapis.com/auth/compute"

	// View your Google Compute Engine resources
	ComputeReadonlyScope = "https://www.googleapis.com/auth/compute.readonly"

	// Manage your data and permissions in Google Cloud Storage
	DevstorageFullControlScope = "https://www.googleapis.com/auth/devstorage.full_control"

	// View your data in Google Cloud Storage
	DevstorageReadOnlyScope = "https://www.googleapis.com/auth/devstorage.read_only"

	// Manage your data in Google Cloud Storage
	DevstorageReadWriteScope = "https://www.googleapis.com/auth/devstorage.read_write"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
		"https://www.googleapis.com/auth/compute",
		"https://www.googleapis.com/auth/compute.readonly",
		"https://www.googleapis.com/auth/devstorage.full_control",
		"https://www.googleapis.com/auth/devstorage.read_only",
		"https://www.googleapis.com/auth/devstorage.read_write",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.AcceleratorTypes = NewAcceleratorTypesService(s)
	s.Addresses = NewAddressesService(s)
	s.Autoscalers = NewAutoscalersService(s)
	s.BackendBuckets = NewBackendBucketsService(s)
	s.BackendServices = NewBackendServicesService(s)
	s.DiskTypes = NewDiskTypesService(s)
	s.Disks = NewDisksService(s)
	s.ExternalVpnGateways = NewExternalVpnGatewaysService(s)
	s.Firewalls = NewFirewallsService(s)
	s.ForwardingRules = NewForwardingRulesService(s)
	s.GlobalAddresses = NewGlobalAddressesService(s)
	s.GlobalForwardingRules = NewGlobalForwardingRulesService(s)
	s.GlobalOperations = NewGlobalOperationsService(s)
	s.HealthChecks = NewHealthChecksService(s)
	s.HttpHealthChecks = NewHttpHealthChecksService(s)
	s.HttpsHealthChecks = NewHttpsHealthChecksService(s)
	s.Images = NewImagesService(s)
	s.InstanceGroupManagers = NewInstanceGroupManagersService(s)
	s.InstanceGroups = NewInstanceGroupsService(s)
	s.InstanceTemplates = NewInstanceTemplatesService(s)
	s.Instances = NewInstancesService(s)
	s.InterconnectAttachments = NewInterconnectAttachmentsService(s)
	s.InterconnectLocations = NewInterconnectLocationsService(s)
	s.Interconnects = NewInterconnectsService(s)
	s.LicenseCodes = NewLicenseCodesService(s)
	s.Licenses = NewLicensesService(s)
	s.MachineTypes = NewMachineTypesService(s)
	s.NetworkEndpointGroups = NewNetworkEndpointGroupsService(s)
	s.Networks = NewNetworksService(s)
	s.NodeGroups = NewNodeGroupsService(s)
	s.NodeTemplates = NewNodeTemplatesService(s)
	s.NodeTypes = NewNodeTypesService(s)
	s.Projects = NewProjectsService(s)
	s.RegionAutoscalers = NewRegionAutoscalersService(s)
	s.RegionBackendServices = NewRegionBackendServicesService(s)
	s.RegionCommitments = NewRegionCommitmentsService(s)
	s.RegionDiskTypes = NewRegionDiskTypesService(s)
	s.RegionDisks = NewRegionDisksService(s)
	s.RegionHealthChecks = NewRegionHealthChecksService(s)
	s.RegionInstanceGroupManagers = NewRegionInstanceGroupManagersService(s)
	s.RegionInstanceGroups = NewRegionInstanceGroupsService(s)
	s.RegionOperations = NewRegionOperationsService(s)
	s.RegionSslCertificates = NewRegionSslCertificatesService(s)
	s.RegionTargetHttpProxies = NewRegionTargetHttpProxiesService(s)
	s.RegionTargetHttpsProxies = NewRegionTargetHttpsProxiesService(s)
	s.RegionUrlMaps = NewRegionUrlMapsService(s)
	s.Regions = NewRegionsService(s)
	s.Reservations = NewReservationsService(s)
	s.ResourcePolicies = NewResourcePoliciesService(s)
	s.Routers = NewRoutersService(s)
	s.Routes = NewRoutesService(s)
	s.SecurityPolicies = NewSecurityPoliciesService(s)
	s.Snapshots = NewSnapshotsService(s)
	s.SslCertificates = NewSslCertificatesService(s)
	s.SslPolicies = NewSslPoliciesService(s)
	s.Subnetworks = NewSubnetworksService(s)
	s.TargetHttpProxies = NewTargetHttpProxiesService(s)
	s.TargetHttpsProxies = NewTargetHttpsProxiesService(s)
	s.TargetInstances = NewTargetInstancesService(s)
	s.TargetPools = NewTargetPoolsService(s)
	s.TargetSslProxies = NewTargetSslProxiesService(s)
	s.TargetTcpProxies = NewTargetTcpProxiesService(s)
	s.TargetVpnGateways = NewTargetVpnGatewaysService(s)
	s.UrlMaps = NewUrlMapsService(s)
	s.VpnGateways = NewVpnGatewaysService(s)
	s.VpnTunnels = NewVpnTunnelsService(s)
	s.ZoneOperations = NewZoneOperationsService(s)
	s.Zones = NewZonesService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	AcceleratorTypes *AcceleratorTypesService

	Addresses *AddressesService

	Autoscalers *AutoscalersService

	BackendBuckets *BackendBucketsService

	BackendServices *BackendServicesService

	DiskTypes *DiskTypesService

	Disks *DisksService

	ExternalVpnGateways *ExternalVpnGatewaysService

	Firewalls *FirewallsService

	ForwardingRules *ForwardingRulesService

	GlobalAddresses *GlobalAddressesService

	GlobalForwardingRules *GlobalForwardingRulesService

	GlobalOperations *GlobalOperationsService

	HealthChecks *HealthChecksService

	HttpHealthChecks *HttpHealthChecksService

	HttpsHealthChecks *HttpsHealthChecksService

	Images *ImagesService

	InstanceGroupManagers *InstanceGroupManagersService

	InstanceGroups *InstanceGroupsService

	InstanceTemplates *InstanceTemplatesService

	Instances *InstancesService

	InterconnectAttachments *InterconnectAttachmentsService

	InterconnectLocations *InterconnectLocationsService

	Interconnects *InterconnectsService

	LicenseCodes *LicenseCodesService

	Licenses *LicensesService

	MachineTypes *MachineTypesService

	NetworkEndpointGroups *NetworkEndpointGroupsService

	Networks *NetworksService

	NodeGroups *NodeGroupsService

	NodeTemplates *NodeTemplatesService

	NodeTypes *NodeTypesService

	Projects *ProjectsService

	RegionAutoscalers *RegionAutoscalersService

	RegionBackendServices *RegionBackendServicesService

	RegionCommitments *RegionCommitmentsService

	RegionDiskTypes *RegionDiskTypesService

	RegionDisks *RegionDisksService

	RegionHealthChecks *RegionHealthChecksService

	RegionInstanceGroupManagers *RegionInstanceGroupManagersService

	RegionInstanceGroups *RegionInstanceGroupsService

	RegionOperations *RegionOperationsService

	RegionSslCertificates *RegionSslCertificatesService

	RegionTargetHttpProxies *RegionTargetHttpProxiesService

	RegionTargetHttpsProxies *RegionTargetHttpsProxiesService

	RegionUrlMaps *RegionUrlMapsService

	Regions *RegionsService

	Reservations *ReservationsService

	ResourcePolicies *ResourcePoliciesService

	Routers *RoutersService

	Routes *RoutesService

	SecurityPolicies *SecurityPoliciesService

	Snapshots *SnapshotsService

	SslCertificates *SslCertificatesService

	SslPolicies *SslPoliciesService

	Subnetworks *SubnetworksService

	TargetHttpProxies *TargetHttpProxiesService

	TargetHttpsProxies *TargetHttpsProxiesService

	TargetInstances *TargetInstancesService

	TargetPools *TargetPoolsService

	TargetSslProxies *TargetSslProxiesService

	TargetTcpProxies *TargetTcpProxiesService

	TargetVpnGateways *TargetVpnGatewaysService

	UrlMaps *UrlMapsService

	VpnGateways *VpnGatewaysService

	VpnTunnels *VpnTunnelsService

	ZoneOperations *ZoneOperationsService

	Zones *ZonesService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewAcceleratorTypesService(s *Service) *AcceleratorTypesService {
	rs := &AcceleratorTypesService{s: s}
	return rs
}

type AcceleratorTypesService struct {
	s *Service
}

func NewAddressesService(s *Service) *AddressesService {
	rs := &AddressesService{s: s}
	return rs
}

type AddressesService struct {
	s *Service
}

func NewAutoscalersService(s *Service) *AutoscalersService {
	rs := &AutoscalersService{s: s}
	return rs
}

type AutoscalersService struct {
	s *Service
}

func NewBackendBucketsService(s *Service) *BackendBucketsService {
	rs := &BackendBucketsService{s: s}
	return rs
}

type BackendBucketsService struct {
	s *Service
}

func NewBackendServicesService(s *Service) *BackendServicesService {
	rs := &BackendServicesService{s: s}
	return rs
}

type BackendServicesService struct {
	s *Service
}

func NewDiskTypesService(s *Service) *DiskTypesService {
	rs := &DiskTypesService{s: s}
	return rs
}

type DiskTypesService struct {
	s *Service
}

func NewDisksService(s *Service) *DisksService {
	rs := &DisksService{s: s}
	return rs
}

type DisksService struct {
	s *Service
}

func NewExternalVpnGatewaysService(s *Service) *ExternalVpnGatewaysService {
	rs := &ExternalVpnGatewaysService{s: s}
	return rs
}

type ExternalVpnGatewaysService struct {
	s *Service
}

func NewFirewallsService(s *Service) *FirewallsService {
	rs := &FirewallsService{s: s}
	return rs
}

type FirewallsService struct {
	s *Service
}

func NewForwardingRulesService(s *Service) *ForwardingRulesService {
	rs := &ForwardingRulesService{s: s}
	return rs
}

type ForwardingRulesService struct {
	s *Service
}

func NewGlobalAddressesService(s *Service) *GlobalAddressesService {
	rs := &GlobalAddressesService{s: s}
	return rs
}

type GlobalAddressesService struct {
	s *Service
}

func NewGlobalForwardingRulesService(s *Service) *GlobalForwardingRulesService {
	rs := &GlobalForwardingRulesService{s: s}
	return rs
}

type GlobalForwardingRulesService struct {
	s *Service
}

func NewGlobalOperationsService(s *Service) *GlobalOperationsService {
	rs := &GlobalOperationsService{s: s}
	return rs
}

type GlobalOperationsService struct {
	s *Service
}

func NewHealthChecksService(s *Service) *HealthChecksService {
	rs := &HealthChecksService{s: s}
	return rs
}

type HealthChecksService struct {
	s *Service
}

func NewHttpHealthChecksService(s *Service) *HttpHealthChecksService {
	rs := &HttpHealthChecksService{s: s}
	return rs
}

type HttpHealthChecksService struct {
	s *Service
}

func NewHttpsHealthChecksService(s *Service) *HttpsHealthChecksService {
	rs := &HttpsHealthChecksService{s: s}
	return rs
}

type HttpsHealthChecksService struct {
	s *Service
}

func NewImagesService(s *Service) *ImagesService {
	rs := &ImagesService{s: s}
	return rs
}

type ImagesService struct {
	s *Service
}

func NewInstanceGroupManagersService(s *Service) *InstanceGroupManagersService {
	rs := &InstanceGroupManagersService{s: s}
	return rs
}

type InstanceGroupManagersService struct {
	s *Service
}

func NewInstanceGroupsService(s *Service) *InstanceGroupsService {
	rs := &InstanceGroupsService{s: s}
	return rs
}

type InstanceGroupsService struct {
	s *Service
}

func NewInstanceTemplatesService(s *Service) *InstanceTemplatesService {
	rs := &InstanceTemplatesService{s: s}
	return rs
}

type InstanceTemplatesService struct {
	s *Service
}

func NewInstancesService(s *Service) *InstancesService {
	rs := &InstancesService{s: s}
	return rs
}

type InstancesService struct {
	s *Service
}

func NewInterconnectAttachmentsService(s *Service) *InterconnectAttachmentsService {
	rs := &InterconnectAttachmentsService{s: s}
	return rs
}

type InterconnectAttachmentsService struct {
	s *Service
}

func NewInterconnectLocationsService(s *Service) *InterconnectLocationsService {
	rs := &InterconnectLocationsService{s: s}
	return rs
}

type InterconnectLocationsService struct {
	s *Service
}

func NewInterconnectsService(s *Service) *InterconnectsService {
	rs := &InterconnectsService{s: s}
	return rs
}

type InterconnectsService struct {
	s *Service
}

func NewLicenseCodesService(s *Service) *LicenseCodesService {
	rs := &LicenseCodesService{s: s}
	return rs
}

type LicenseCodesService struct {
	s *Service
}

func NewLicensesService(s *Service) *LicensesService {
	rs := &LicensesService{s: s}
	return rs
}

type LicensesService struct {
	s *Service
}

func NewMachineTypesService(s *Service) *MachineTypesService {
	rs := &MachineTypesService{s: s}
	return rs
}

type MachineTypesService struct {
	s *Service
}

func NewNetworkEndpointGroupsService(s *Service) *NetworkEndpointGroupsService {
	rs := &NetworkEndpointGroupsService{s: s}
	return rs
}

type NetworkEndpointGroupsService struct {
	s *Service
}

func NewNetworksService(s *Service) *NetworksService {
	rs := &NetworksService{s: s}
	return rs
}

type NetworksService struct {
	s *Service
}

func NewNodeGroupsService(s *Service) *NodeGroupsService {
	rs := &NodeGroupsService{s: s}
	return rs
}

type NodeGroupsService struct {
	s *Service
}

func NewNodeTemplatesService(s *Service) *NodeTemplatesService {
	rs := &NodeTemplatesService{s: s}
	return rs
}

type NodeTemplatesService struct {
	s *Service
}

func NewNodeTypesService(s *Service) *NodeTypesService {
	rs := &NodeTypesService{s: s}
	return rs
}

type NodeTypesService struct {
	s *Service
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	return rs
}

type ProjectsService struct {
	s *Service
}

func NewRegionAutoscalersService(s *Service) *RegionAutoscalersService {
	rs := &RegionAutoscalersService{s: s}
	return rs
}

type RegionAutoscalersService struct {
	s *Service
}

func NewRegionBackendServicesService(s *Service) *RegionBackendServicesService {
	rs := &RegionBackendServicesService{s: s}
	return rs
}

type RegionBackendServicesService struct {
	s *Service
}

func NewRegionCommitmentsService(s *Service) *RegionCommitmentsService {
	rs := &RegionCommitmentsService{s: s}
	return rs
}

type RegionCommitmentsService struct {
	s *Service
}

func NewRegionDiskTypesService(s *Service) *RegionDiskTypesService {
	rs := &RegionDiskTypesService{s: s}
	return rs
}

type RegionDiskTypesService struct {
	s *Service
}

func NewRegionDisksService(s *Service) *RegionDisksService {
	rs := &RegionDisksService{s: s}
	return rs
}

type RegionDisksService struct {
	s *Service
}

func NewRegionHealthChecksService(s *Service) *RegionHealthChecksService {
	rs := &RegionHealthChecksService{s: s}
	return rs
}

type RegionHealthChecksService struct {
	s *Service
}

func NewRegionInstanceGroupManagersService(s *Service) *RegionInstanceGroupManagersService {
	rs := &RegionInstanceGroupManagersService{s: s}
	return rs
}

type RegionInstanceGroupManagersService struct {
	s *Service
}

func NewRegionInstanceGroupsService(s *Service) *RegionInstanceGroupsService {
	rs := &RegionInstanceGroupsService{s: s}
	return rs
}

type RegionInstanceGroupsService struct {
	s *Service
}

func NewRegionOperationsService(s *Service) *RegionOperationsService {
	rs := &RegionOperationsService{s: s}
	return rs
}

type RegionOperationsService struct {
	s *Service
}

func NewRegionSslCertificatesService(s *Service) *RegionSslCertificatesService {
	rs := &RegionSslCertificatesService{s: s}
	return rs
}

type RegionSslCertificatesService struct {
	s *Service
}

func NewRegionTargetHttpProxiesService(s *Service) *RegionTargetHttpProxiesService {
	rs := &RegionTargetHttpProxiesService{s: s}
	return rs
}

type RegionTargetHttpProxiesService struct {
	s *Service
}

func NewRegionTargetHttpsProxiesService(s *Service) *RegionTargetHttpsProxiesService {
	rs := &RegionTargetHttpsProxiesService{s: s}
	return rs
}

type RegionTargetHttpsProxiesService struct {
	s *Service
}

func NewRegionUrlMapsService(s *Service) *RegionUrlMapsService {
	rs := &RegionUrlMapsService{s: s}
	return rs
}

type RegionUrlMapsService struct {
	s *Service
}

func NewRegionsService(s *Service) *RegionsService {
	rs := &RegionsService{s: s}
	return rs
}

type RegionsService struct {
	s *Service
}

func NewReservationsService(s *Service) *ReservationsService {
	rs := &ReservationsService{s: s}
	return rs
}

type ReservationsService struct {
	s *Service
}

func NewResourcePoliciesService(s *Service) *ResourcePoliciesService {
	rs := &ResourcePoliciesService{s: s}
	return rs
}

type ResourcePoliciesService struct {
	s *Service
}

func NewRoutersService(s *Service) *RoutersService {
	rs := &RoutersService{s: s}
	return rs
}

type RoutersService struct {
	s *Service
}

func NewRoutesService(s *Service) *RoutesService {
	rs := &RoutesService{s: s}
	return rs
}

type RoutesService struct {
	s *Service
}

func NewSecurityPoliciesService(s *Service) *SecurityPoliciesService {
	rs := &SecurityPoliciesService{s: s}
	return rs
}

type SecurityPoliciesService struct {
	s *Service
}

func NewSnapshotsService(s *Service) *SnapshotsService {
	rs := &SnapshotsService{s: s}
	return rs
}

type SnapshotsService struct {
	s *Service
}

func NewSslCertificatesService(s *Service) *SslCertificatesService {
	rs := &SslCertificatesService{s: s}
	return rs
}

type SslCertificatesService struct {
	s *Service
}

func NewSslPoliciesService(s *Service) *SslPoliciesService {
	rs := &SslPoliciesService{s: s}
	return rs
}

type SslPoliciesService struct {
	s *Service
}

func NewSubnetworksService(s *Service) *SubnetworksService {
	rs := &SubnetworksService{s: s}
	return rs
}

type SubnetworksService struct {
	s *Service
}

func NewTargetHttpProxiesService(s *Service) *TargetHttpProxiesService {
	rs := &TargetHttpProxiesService{s: s}
	return rs
}

type TargetHttpProxiesService struct {
	s *Service
}

func NewTargetHttpsProxiesService(s *Service) *TargetHttpsProxiesService {
	rs := &TargetHttpsProxiesService{s: s}
	return rs
}

type TargetHttpsProxiesService struct {
	s *Service
}

func NewTargetInstancesService(s *Service) *TargetInstancesService {
	rs := &TargetInstancesService{s: s}
	return rs
}

type TargetInstancesService struct {
	s *Service
}

func NewTargetPoolsService(s *Service) *TargetPoolsService {
	rs := &TargetPoolsService{s: s}
	return rs
}

type TargetPoolsService struct {
	s *Service
}

func NewTargetSslProxiesService(s *Service) *TargetSslProxiesService {
	rs := &TargetSslProxiesService{s: s}
	return rs
}

type TargetSslProxiesService struct {
	s *Service
}

func NewTargetTcpProxiesService(s *Service) *TargetTcpProxiesService {
	rs := &TargetTcpProxiesService{s: s}
	return rs
}

type TargetTcpProxiesService struct {
	s *Service
}

func NewTargetVpnGatewaysService(s *Service) *TargetVpnGatewaysService {
	rs := &TargetVpnGatewaysService{s: s}
	return rs
}

type TargetVpnGatewaysService struct {
	s *Service
}

func NewUrlMapsService(s *Service) *UrlMapsService {
	rs := &UrlMapsService{s: s}
	return rs
}

type UrlMapsService struct {
	s *Service
}

func NewVpnGatewaysService(s *Service) *VpnGatewaysService {
	rs := &VpnGatewaysService{s: s}
	return rs
}

type VpnGatewaysService struct {
	s *Service
}

func NewVpnTunnelsService(s *Service) *VpnTunnelsService {
	rs := &VpnTunnelsService{s: s}
	return rs
}

type VpnTunnelsService struct {
	s *Service
}

func NewZoneOperationsService(s *Service) *ZoneOperationsService {
	rs := &ZoneOperationsService{s: s}
	return rs
}

type ZoneOperationsService struct {
	s *Service
}

func NewZonesService(s *Service) *ZonesService {
	rs := &ZonesService{s: s}
	return rs
}

type ZonesService struct {
	s *Service
}

// AcceleratorConfig: A specification of the type and number of
// accelerator cards attached to the instance.
type AcceleratorConfig struct {
	// AcceleratorCount: The number of the guest accelerator cards exposed
	// to this instance.
	AcceleratorCount int64 `json:"acceleratorCount,omitempty"`

	// AcceleratorType: Full or partial URL of the accelerator type resource
	// to attach to this instance. For example:
	// projects/my-project/zones/us-central1-c/acceleratorTypes/nvidia-tesla-
	// p100 If you are creating an instance template, specify only the
	// accelerator name. See GPUs on Compute Engine for a full list of
	// accelerator types.
	AcceleratorType string `json:"acceleratorType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AcceleratorCount") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AcceleratorCount") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AcceleratorType: Represents an Accelerator Type resource.
//
// Google Cloud Platform provides graphics processing units
// (accelerators) that you can add to VM instances to improve or
// accelerate performance when working with intensive workloads. For
// more information, read GPUs on Compute Engine. (== resource_for
// beta.acceleratorTypes ==) (== resource_for v1.acceleratorTypes ==)
type AcceleratorType struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Deprecated: [Output Only] The deprecation status associated with this
	// accelerator type.
	Deprecated *DeprecationStatus `json:"deprecated,omitempty"`

	// Description: [Output Only] An optional textual description of the
	// resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] The type of the resource. Always
	// compute#acceleratorType for accelerator types.
	Kind string `json:"kind,omitempty"`

	// MaximumCardsPerInstance: [Output Only] Maximum accelerator cards
	// allowed per instance.
	MaximumCardsPerInstance int64 `json:"maximumCardsPerInstance,omitempty"`

	// Name: [Output Only] Name of the resource.
	Name string `json:"name,omitempty"`

	// SelfLink: [Output Only] Server-defined fully-qualified URL for this
	// resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Zone: [Output Only] The name of the zone where the accelerator type
	// resides, such as us-central1-a. You must specify this field as part
	// of the HTTP request URL. It is not settable as a field in the request
	// body.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorType) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AcceleratorTypeAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of AcceleratorTypesScopedList resources.
	Items map[string]AcceleratorTypesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#acceleratorTypeAggregatedList for aggregated lists of
	// accelerator types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *AcceleratorTypeAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypeAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypeAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AcceleratorTypeAggregatedListWarning: [Output Only] Informational
// warning message.
type AcceleratorTypeAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AcceleratorTypeAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypeAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypeAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AcceleratorTypeAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypeAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypeAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AcceleratorTypeList: Contains a list of accelerator types.
type AcceleratorTypeList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of AcceleratorType resources.
	Items []*AcceleratorType `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#acceleratorTypeList for lists of accelerator types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *AcceleratorTypeListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypeList) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypeList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AcceleratorTypeListWarning: [Output Only] Informational warning
// message.
type AcceleratorTypeListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AcceleratorTypeListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypeListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypeListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AcceleratorTypeListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypeListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypeListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AcceleratorTypesScopedList struct {
	// AcceleratorTypes: [Output Only] A list of accelerator types contained
	// in this scope.
	AcceleratorTypes []*AcceleratorType `json:"acceleratorTypes,omitempty"`

	// Warning: [Output Only] An informational warning that appears when the
	// accelerator types list is empty.
	Warning *AcceleratorTypesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AcceleratorTypes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AcceleratorTypes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AcceleratorTypesScopedListWarning: [Output Only] An informational
// warning that appears when the accelerator types list is empty.
type AcceleratorTypesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AcceleratorTypesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AcceleratorTypesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AcceleratorTypesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AcceleratorTypesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AccessConfig: An access configuration attached to an instance's
// network interface. Only one access config per instance is supported.
type AccessConfig struct {
	// Kind: [Output Only] Type of the resource. Always compute#accessConfig
	// for access configs.
	Kind string `json:"kind,omitempty"`

	// Name: The name of this access configuration. The default and
	// recommended name is External NAT, but you can use any arbitrary
	// string, such as My external IP or Network Access.
	Name string `json:"name,omitempty"`

	// NatIP: An external IP address associated with this instance. Specify
	// an unused static external IP address available to the project or
	// leave this field undefined to use an IP from a shared ephemeral IP
	// address pool. If you specify a static external IP address, it must
	// live in the same region as the zone of the instance.
	NatIP string `json:"natIP,omitempty"`

	// NetworkTier: This signifies the networking tier used for configuring
	// this access configuration and can only take the following values:
	// PREMIUM, STANDARD.
	//
	// If an AccessConfig is specified without a valid external IP address,
	// an ephemeral IP will be created with this networkTier.
	//
	// If an AccessConfig with a valid external IP address is specified, it
	// must match that of the networkTier associated with the Address
	// resource owning that IP.
	//
	// Possible values:
	//   "PREMIUM"
	//   "STANDARD"
	NetworkTier string `json:"networkTier,omitempty"`

	// PublicPtrDomainName: The DNS domain name for the public PTR record.
	// You can set this field only if the `setPublicPtr` field is enabled.
	PublicPtrDomainName string `json:"publicPtrDomainName,omitempty"`

	// SetPublicPtr: Specifies whether a public DNS 'PTR' record should be
	// created to map the external IP address of the instance to a DNS
	// domain name.
	SetPublicPtr bool `json:"setPublicPtr,omitempty"`

	// Type: The type of configuration. The default and only option is
	// ONE_TO_ONE_NAT.
	//
	// Possible values:
	//   "ONE_TO_ONE_NAT" (default)
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AccessConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AccessConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Address: Represents an IP Address resource.
//
// An address resource represents a regional internal IP address.
// Regional internal IP addresses are RFC 1918 addresses that come from
// either a primary or secondary IP range of a subnet in a VPC network.
// Regional external IP addresses can be assigned to GCP VM instances,
// Cloud VPN gateways, regional external forwarding rules for network
// load balancers (in either Standard or Premium Tier), and regional
// external forwarding rules for HTTP(S), SSL Proxy, and TCP Proxy load
// balancers in Standard Tier. For more information, read IP
// addresses.
//
// A globalAddresses resource represent a global external IP address.
// Global external IP addresses are IPv4 or IPv6 addresses. They can
// only be assigned to global forwarding rules for HTTP(S), SSL Proxy,
// or TCP Proxy load balancers in Premium Tier. For more information,
// read Global resources. (== resource_for beta.addresses ==) (==
// resource_for v1.addresses ==) (== resource_for beta.globalAddresses
// ==) (== resource_for v1.globalAddresses ==)
type Address struct {
	// Address: The static IP address represented by this resource.
	Address string `json:"address,omitempty"`

	// AddressType: The type of address to reserve, either INTERNAL or
	// EXTERNAL. If unspecified, defaults to EXTERNAL.
	//
	// Possible values:
	//   "EXTERNAL"
	//   "INTERNAL"
	//   "UNSPECIFIED_TYPE"
	AddressType string `json:"addressType,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// field when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// IpVersion: The IP version that will be used by this address. Valid
	// options are IPV4 or IPV6. This can only be specified for a global
	// address.
	//
	// Possible values:
	//   "IPV4"
	//   "IPV6"
	//   "UNSPECIFIED_VERSION"
	IpVersion string `json:"ipVersion,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#address for
	// addresses.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?`. The first
	// character must be a lowercase letter, and all following characters
	// (except for the last character) must be a dash, lowercase letter, or
	// digit. The last character must be a lowercase letter or digit.
	Name string `json:"name,omitempty"`

	// Network: The URL of the network in which to reserve the address. This
	// field can only be used with INTERNAL type with the VPC_PEERING
	// purpose.
	Network string `json:"network,omitempty"`

	// NetworkTier: This signifies the networking tier used for configuring
	// this address and can only take the following values: PREMIUM or
	// STANDARD. Global forwarding rules can only be Premium Tier. Regional
	// forwarding rules can be either Premium or Standard Tier. Standard
	// Tier addresses applied to regional forwarding rules can be used with
	// any external load balancer. Regional forwarding rules in Premium Tier
	// can only be used with a network load balancer.
	//
	// If this field is not specified, it is assumed to be PREMIUM.
	//
	// Possible values:
	//   "PREMIUM"
	//   "STANDARD"
	NetworkTier string `json:"networkTier,omitempty"`

	// PrefixLength: The prefix length if the resource reprensents an IP
	// range.
	PrefixLength int64 `json:"prefixLength,omitempty"`

	// Purpose: The purpose of this resource, which can be one of the
	// following values:
	// - `GCE_ENDPOINT` for addresses that are used by VM instances, alias
	// IP ranges, internal load balancers, and similar resources.
	// - `DNS_RESOLVER` for a DNS resolver address in a subnetwork
	// - `VPC_PEERING` for addresses that are reserved for VPC peer
	// networks.
	// - `NAT_AUTO` for addresses that are external IP addresses
	// automatically reserved for Cloud NAT.
	//
	// Possible values:
	//   "DNS_RESOLVER"
	//   "GCE_ENDPOINT"
	//   "NAT_AUTO"
	//   "VPC_PEERING"
	Purpose string `json:"purpose,omitempty"`

	// Region: [Output Only] The URL of the region where the regional
	// address resides. This field is not applicable to global addresses.
	// You must specify this field as part of the HTTP request URL.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Status: [Output Only] The status of the address, which can be one of
	// RESERVING, RESERVED, or IN_USE. An address that is RESERVING is
	// currently in the process of being reserved. A RESERVED address is
	// currently reserved and available to use. An IN_USE address is
	// currently being used by another resource and is not available.
	//
	// Possible values:
	//   "IN_USE"
	//   "RESERVED"
	//   "RESERVING"
	Status string `json:"status,omitempty"`

	// Subnetwork: The URL of the subnetwork in which to reserve the
	// address. If an IP address is specified, it must be within the
	// subnetwork's IP range. This field can only be used with INTERNAL type
	// with a GCE_ENDPOINT or DNS_RESOLVER purpose.
	Subnetwork string `json:"subnetwork,omitempty"`

	// Users: [Output Only] The URLs of the resources that are using this
	// address.
	Users []string `json:"users,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Address") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Address") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Address) MarshalJSON() ([]byte, error) {
	type NoMethod Address
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AddressAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of AddressesScopedList resources.
	Items map[string]AddressesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#addressAggregatedList for aggregated lists of addresses.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *AddressAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod AddressAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddressAggregatedListWarning: [Output Only] Informational warning
// message.
type AddressAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AddressAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AddressAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AddressAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AddressAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddressList: Contains a list of addresses.
type AddressList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Address resources.
	Items []*Address `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#addressList for
	// lists of addresses.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *AddressListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressList) MarshalJSON() ([]byte, error) {
	type NoMethod AddressList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddressListWarning: [Output Only] Informational warning message.
type AddressListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AddressListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AddressListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AddressListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AddressListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AddressesScopedList struct {
	// Addresses: [Output Only] A list of addresses contained in this scope.
	Addresses []*Address `json:"addresses,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of addresses when the list is empty.
	Warning *AddressesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Addresses") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Addresses") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod AddressesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddressesScopedListWarning: [Output Only] Informational warning which
// replaces the list of addresses when the list is empty.
type AddressesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AddressesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AddressesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AddressesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AddressesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AddressesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AliasIpRange: An alias IP range attached to an instance's network
// interface.
type AliasIpRange struct {
	// IpCidrRange: The IP alias ranges to allocate for this interface. This
	// IP CIDR range must belong to the specified subnetwork and cannot
	// contain IP addresses reserved by system or used by other network
	// interfaces. This range may be a single IP address (such as 10.2.3.4),
	// a netmask (such as /24) or a CIDR-formatted string (such as
	// 10.1.2.0/24).
	IpCidrRange string `json:"ipCidrRange,omitempty"`

	// SubnetworkRangeName: The name of a subnetwork secondary IP range from
	// which to allocate an IP alias range. If not specified, the primary
	// range of the subnetwork is used.
	SubnetworkRangeName string `json:"subnetworkRangeName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpCidrRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpCidrRange") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AliasIpRange) MarshalJSON() ([]byte, error) {
	type NoMethod AliasIpRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk struct {
	// DiskSizeGb: Specifies the size of the disk in base-2 GB.
	DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"`

	// Interface: Specifies the disk interface to use for attaching this
	// disk, which is either SCSI or NVME. The default is SCSI. For
	// performance characteristics of SCSI over NVMe, see Local SSD
	// performance.
	//
	// Possible values:
	//   "NVME"
	//   "SCSI"
	Interface string `json:"interface,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DiskSizeGb") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DiskSizeGb") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk) MarshalJSON() ([]byte, error) {
	type NoMethod AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AllocationSpecificSKUAllocationReservedInstanceProperties: Properties
// of the SKU instances being reserved.
type AllocationSpecificSKUAllocationReservedInstanceProperties struct {
	// GuestAccelerators: Specifies accelerator type and count.
	GuestAccelerators []*AcceleratorConfig `json:"guestAccelerators,omitempty"`

	// LocalSsds: Specifies amount of local ssd to reserve with each
	// instance. The type of disk is local-ssd.
	LocalSsds []*AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk `json:"localSsds,omitempty"`

	// MachineType: Specifies type of machine (name only) which has fixed
	// number of vCPUs and fixed amount of memory. This also includes
	// specifying custom machine type following
	// custom-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY pattern.
	MachineType string `json:"machineType,omitempty"`

	// MinCpuPlatform: Minimum cpu platform the reservation.
	MinCpuPlatform string `json:"minCpuPlatform,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GuestAccelerators")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GuestAccelerators") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AllocationSpecificSKUAllocationReservedInstanceProperties) MarshalJSON() ([]byte, error) {
	type NoMethod AllocationSpecificSKUAllocationReservedInstanceProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AllocationSpecificSKUReservation: This reservation type allows to pre
// allocate specific instance configuration.
type AllocationSpecificSKUReservation struct {
	// Count: Specifies the number of resources that are allocated.
	Count int64 `json:"count,omitempty,string"`

	// InUseCount: [Output Only] Indicates how many instances are in use.
	InUseCount int64 `json:"inUseCount,omitempty,string"`

	// InstanceProperties: The instance properties for the reservation.
	InstanceProperties *AllocationSpecificSKUAllocationReservedInstanceProperties `json:"instanceProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Count") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Count") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AllocationSpecificSKUReservation) MarshalJSON() ([]byte, error) {
	type NoMethod AllocationSpecificSKUReservation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AttachedDisk: An instance-attached disk resource.
type AttachedDisk struct {
	// AutoDelete: Specifies whether the disk will be auto-deleted when the
	// instance is deleted (but not when the disk is detached from the
	// instance).
	AutoDelete bool `json:"autoDelete,omitempty"`

	// Boot: Indicates that this is a boot disk. The virtual machine will
	// use the first partition of the disk for its root filesystem.
	Boot bool `json:"boot,omitempty"`

	// DeviceName: Specifies a unique device name of your choice that is
	// reflected into the /dev/disk/by-id/google-* tree of a Linux operating
	// system running within the instance. This name can be used to
	// reference the device for mounting, resizing, and so on, from within
	// the instance.
	//
	// If not specified, the server chooses a default device name to apply
	// to this disk, in the form persistent-disk-x, where x is a number
	// assigned by Google Compute Engine. This field is only applicable for
	// persistent disks.
	DeviceName string `json:"deviceName,omitempty"`

	// DiskEncryptionKey: Encrypts or decrypts a disk using a
	// customer-supplied encryption key.
	//
	// If you are creating a new disk, this field encrypts the new disk
	// using an encryption key that you provide. If you are attaching an
	// existing disk that is already encrypted, this field decrypts the disk
	// using the customer-supplied encryption key.
	//
	// If you encrypt a disk using a customer-supplied key, you must provide
	// the same key again when you attempt to use this resource at a later
	// time. For example, you must provide the key when you create a
	// snapshot or an image from the disk or when you attach the disk to a
	// virtual machine instance.
	//
	// If you do not provide an encryption key, then the disk will be
	// encrypted using an automatically generated key and you do not need to
	// provide a key to use the disk later.
	//
	// Instance templates do not store customer-supplied encryption keys, so
	// you cannot use your own keys to encrypt disks in a managed instance
	// group.
	DiskEncryptionKey *CustomerEncryptionKey `json:"diskEncryptionKey,omitempty"`

	// GuestOsFeatures: A list of features to enable on the guest operating
	// system. Applicable only for bootable images. Read  Enabling guest
	// operating system features to see a list of available options.
	GuestOsFeatures []*GuestOsFeature `json:"guestOsFeatures,omitempty"`

	// Index: [Output Only] A zero-based index to this disk, where 0 is
	// reserved for the boot disk. If you have many disks attached to an
	// instance, each disk would have a unique index number.
	Index int64 `json:"index,omitempty"`

	// InitializeParams: [Input Only] Specifies the parameters for a new
	// disk that will be created alongside the new instance. Use
	// initialization parameters to create boot disks or local SSDs attached
	// to the new instance.
	//
	// This property is mutually exclusive with the source property; you can
	// only define one or the other, but not both.
	InitializeParams *AttachedDiskInitializeParams `json:"initializeParams,omitempty"`

	// Interface: Specifies the disk interface to use for attaching this
	// disk, which is either SCSI or NVME. The default is SCSI. Persistent
	// disks must always use SCSI and the request will fail if you attempt
	// to attach a persistent disk in any other format than SCSI. Local SSDs
	// can use either NVME or SCSI. For performance characteristics of SCSI
	// over NVMe, see Local SSD performance. TODO(b/131765817): Update
	// documentation when NVME is supported.
	//
	// Possible values:
	//   "NVME"
	//   "SCSI"
	Interface string `json:"interface,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#attachedDisk
	// for attached disks.
	Kind string `json:"kind,omitempty"`

	// Licenses: [Output Only] Any valid publicly visible licenses.
	Licenses []string `json:"licenses,omitempty"`

	// Mode: The mode in which to attach this disk, either READ_WRITE or
	// READ_ONLY. If not specified, the default is to attach the disk in
	// READ_WRITE mode.
	//
	// Possible values:
	//   "READ_ONLY"
	//   "READ_WRITE"
	Mode string `json:"mode,omitempty"`

	// Source: Specifies a valid partial or full URL to an existing
	// Persistent Disk resource. When creating a new instance, one of
	// initializeParams.sourceImage or initializeParams.sourceSnapshot or
	// disks.source is required except for local SSD.
	//
	// If desired, you can also attach existing non-root persistent disks
	// using this property. This field is only applicable for persistent
	// disks.
	//
	// Note that for InstanceTemplate, specify the disk name, not the URL
	// for the disk.
	Source string `json:"source,omitempty"`

	// Type: Specifies the type of the disk, either SCRATCH or PERSISTENT.
	// If not specified, the default is PERSISTENT.
	//
	// Possible values:
	//   "PERSISTENT"
	//   "SCRATCH"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoDelete") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoDelete") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AttachedDisk) MarshalJSON() ([]byte, error) {
	type NoMethod AttachedDisk
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AttachedDiskInitializeParams: [Input Only] Specifies the parameters
// for a new disk that will be created alongside the new instance. Use
// initialization parameters to create boot disks or local SSDs attached
// to the new instance.
//
// This property is mutually exclusive with the source property; you can
// only define one or the other, but not both.
type AttachedDiskInitializeParams struct {
	// Description: An optional description. Provide this property when
	// creating the disk.
	Description string `json:"description,omitempty"`

	// DiskName: Specifies the disk name. If not specified, the default is
	// to use the name of the instance. If the disk with the instance name
	// exists already in the given zone/region, a new name will be
	// automatically generated.
	DiskName string `json:"diskName,omitempty"`

	// DiskSizeGb: Specifies the size of the disk in base-2 GB. If not
	// specified, the disk will be the same size as the image (usually
	// 10GB). If specified, the size must be equal to or larger than 10GB.
	DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"`

	// DiskType: Specifies the disk type to use to create the instance. If
	// not specified, the default is pd-standard, specified using the full
	// URL. For
	// example:
	// https://www.googleapis.com/compute/v1/projects/project/zones/
	// zone/diskTypes/pd-standard
	//
	//
	// Other values include pd-ssd and local-ssd. If you define this field,
	// you can provide either the full or partial URL. For example, the
	// following are valid values:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/zones/zone/diskTypes/diskType
	// - projects/project/zones/zone/diskTypes/diskType
	// - zones/zone/diskTypes/diskType  Note that for InstanceTemplate, this
	// is the name of the disk type, not URL.
	DiskType string `json:"diskType,omitempty"`

	// Labels: Labels to apply to this disk. These can be later modified by
	// the disks.setLabels method. This field is only applicable for
	// persistent disks.
	Labels map[string]string `json:"labels,omitempty"`

	// ResourcePolicies: Resource policies applied to this disk for
	// automatic snapshot creations. Specified using the full or partial
	// URL. For instance template, specify only the resource policy name.
	ResourcePolicies []string `json:"resourcePolicies,omitempty"`

	// SourceImage: The source image to create this disk. When creating a
	// new instance, one of initializeParams.sourceImage or
	// initializeParams.sourceSnapshot or disks.source is required except
	// for local SSD.
	//
	// To create a disk with one of the public operating system images,
	// specify the image by its family name. For example, specify
	// family/debian-9 to use the latest Debian 9
	// image:
	// projects/debian-cloud/global/images/family/debian-9
	//
	//
	// Alternati
	// vely, use a specific version of a public operating system
	// image:
	// projects/debian-cloud/global/images/debian-9-stretch-vYYYYMMDD
	//
	//
	//
	// To create a disk with a custom image that you created, specify the
	// image name in the following
	// format:
	// global/images/my-custom-image
	//
	//
	// You can also specify a custom image by its image family, which
	// returns the latest version of the image in that family. Replace the
	// image name with
	// family/family-name:
	// global/images/family/my-image-family
	//
	//
	// If the source image is deleted later, this field will not be set.
	SourceImage string `json:"sourceImage,omitempty"`

	// SourceImageEncryptionKey: The customer-supplied encryption key of the
	// source image. Required if the source image is protected by a
	// customer-supplied encryption key.
	//
	// Instance templates do not store customer-supplied encryption keys, so
	// you cannot create disks for instances in a managed instance group if
	// the source images are encrypted with your own keys.
	SourceImageEncryptionKey *CustomerEncryptionKey `json:"sourceImageEncryptionKey,omitempty"`

	// SourceSnapshot: The source snapshot to create this disk. When
	// creating a new instance, one of initializeParams.sourceSnapshot or
	// initializeParams.sourceImage or disks.source is required except for
	// local SSD.
	//
	// To create a disk with a snapshot that you created, specify the
	// snapshot name in the following
	// format:
	// global/snapshots/my-backup
	//
	//
	// If the source snapshot is deleted later, this field will not be set.
	SourceSnapshot string `json:"sourceSnapshot,omitempty"`

	// SourceSnapshotEncryptionKey: The customer-supplied encryption key of
	// the source snapshot.
	SourceSnapshotEncryptionKey *CustomerEncryptionKey `json:"sourceSnapshotEncryptionKey,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AttachedDiskInitializeParams) MarshalJSON() ([]byte, error) {
	type NoMethod AttachedDiskInitializeParams
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AuditConfig: Specifies the audit configuration for a service. The
// configuration determines which permission types are logged, and what
// identities, if any, are exempted from logging. An AuditConfig must
// have one or more AuditLogConfigs.
//
// If there are AuditConfigs for both `allServices` and a specific
// service, the union of the two AuditConfigs is used for that service:
// the log_types specified in each AuditConfig are enabled, and the
// exempted_members in each AuditLogConfig are exempted.
//
// Example Policy with multiple AuditConfigs:
//
// { "audit_configs": [ { "service": "allServices" "audit_log_configs":
// [ { "log_type": "DATA_READ", "exempted_members": [
// "user:jose@example.com" ] }, { "log_type": "DATA_WRITE", }, {
// "log_type": "ADMIN_READ", } ] }, { "service":
// "sampleservice.googleapis.com" "audit_log_configs": [ { "log_type":
// "DATA_READ", }, { "log_type": "DATA_WRITE", "exempted_members": [
// "user:aliya@example.com" ] } ] } ] }
//
// For sampleservice, this policy enables DATA_READ, DATA_WRITE and
// ADMIN_READ logging. It also exempts jose@example.com from DATA_READ
// logging, and aliya@example.com from DATA_WRITE logging.
type AuditConfig struct {
	// AuditLogConfigs: The configuration for logging of each type of
	// permission.
	AuditLogConfigs []*AuditLogConfig `json:"auditLogConfigs,omitempty"`

	ExemptedMembers []string `json:"exemptedMembers,omitempty"`

	// Service: Specifies a service that will be enabled for audit logging.
	// For example, `storage.googleapis.com`, `cloudsql.googleapis.com`.
	// `allServices` is a special value that covers all services.
	Service string `json:"service,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AuditLogConfigs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AuditLogConfigs") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AuditConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AuditConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AuditLogConfig: Provides the configuration for logging a type of
// permissions. Example:
//
// { "audit_log_configs": [ { "log_type": "DATA_READ",
// "exempted_members": [ "user:jose@example.com" ] }, { "log_type":
// "DATA_WRITE", } ] }
//
// This enables 'DATA_READ' and 'DATA_WRITE' logging, while exempting
// jose@example.com from DATA_READ logging.
type AuditLogConfig struct {
	// ExemptedMembers: Specifies the identities that do not cause logging
	// for this type of permission. Follows the same format of
	// [Binding.members][].
	ExemptedMembers []string `json:"exemptedMembers,omitempty"`

	IgnoreChildExemptions bool `json:"ignoreChildExemptions,omitempty"`

	// LogType: The log type that this config enables.
	//
	// Possible values:
	//   "ADMIN_READ"
	//   "DATA_READ"
	//   "DATA_WRITE"
	//   "LOG_TYPE_UNSPECIFIED"
	LogType string `json:"logType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExemptedMembers") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExemptedMembers") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AuditLogConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AuditLogConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AuthorizationLoggingOptions: Authorization-related information used
// by Cloud Audit Logging.
type AuthorizationLoggingOptions struct {
	// PermissionType: The type of the permission that was checked.
	//
	// Possible values:
	//   "ADMIN_READ"
	//   "ADMIN_WRITE"
	//   "DATA_READ"
	//   "DATA_WRITE"
	//   "PERMISSION_TYPE_UNSPECIFIED"
	PermissionType string `json:"permissionType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PermissionType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PermissionType") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AuthorizationLoggingOptions) MarshalJSON() ([]byte, error) {
	type NoMethod AuthorizationLoggingOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Autoscaler: Represents an Autoscaler resource.
//
//
//
// Use autoscalers to automatically add or delete instances from a
// managed instance group according to your defined autoscaling policy.
// For more information, read Autoscaling Groups of Instances.
//
// For zonal managed instance groups resource, use the autoscaler
// resource.
//
// For regional managed instance groups, use the regionAutoscalers
// resource. (== resource_for beta.autoscalers ==) (== resource_for
// v1.autoscalers ==) (== resource_for beta.regionAutoscalers ==) (==
// resource_for v1.regionAutoscalers ==)
type Autoscaler struct {
	// AutoscalingPolicy: The configuration parameters for the autoscaling
	// algorithm. You can define one or more of the policies for an
	// autoscaler: cpuUtilization, customMetricUtilizations, and
	// loadBalancingUtilization.
	//
	// If none of these are specified, the default will be to autoscale
	// based on cpuUtilization to 0.6 or 60%.
	AutoscalingPolicy *AutoscalingPolicy `json:"autoscalingPolicy,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#autoscaler
	// for autoscalers.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Region: [Output Only] URL of the region where the instance group
	// resides (for autoscalers living in regional scope).
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Status: [Output Only] The status of the autoscaler configuration.
	// Current set of possible values: PENDING: Autoscaler backend hasn't
	// read new/updated configuration DELETING: Configuration is being
	// deleted ACTIVE: Configuration is acknowledged to be effective. Some
	// warnings might or might not be present in the status_details field.
	// ERROR: Configuration has errors. Actionable for users. Details are
	// present in the status_details field. New values might be added in the
	// future.
	//
	// Possible values:
	//   "ACTIVE"
	//   "DELETING"
	//   "ERROR"
	//   "PENDING"
	Status string `json:"status,omitempty"`

	// StatusDetails: [Output Only] Human-readable details about the current
	// state of the autoscaler. Read the documentation for Commonly returned
	// status messages for examples of status messages you might encounter.
	StatusDetails []*AutoscalerStatusDetails `json:"statusDetails,omitempty"`

	// Target: URL of the managed instance group that this autoscaler will
	// scale.
	Target string `json:"target,omitempty"`

	// Zone: [Output Only] URL of the zone where the instance group resides
	// (for autoscalers living in zonal scope).
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AutoscalingPolicy")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoscalingPolicy") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Autoscaler) MarshalJSON() ([]byte, error) {
	type NoMethod Autoscaler
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AutoscalerAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of AutoscalersScopedList resources.
	Items map[string]AutoscalersScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#autoscalerAggregatedList for aggregated lists of autoscalers.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *AutoscalerAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalerAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalerAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AutoscalerAggregatedListWarning: [Output Only] Informational warning
// message.
type AutoscalerAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AutoscalerAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalerAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalerAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AutoscalerAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalerAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalerAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AutoscalerList: Contains a list of Autoscaler resources.
type AutoscalerList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Autoscaler resources.
	Items []*Autoscaler `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#autoscalerList
	// for lists of autoscalers.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *AutoscalerListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalerList) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalerList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AutoscalerListWarning: [Output Only] Informational warning message.
type AutoscalerListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AutoscalerListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalerListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalerListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AutoscalerListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalerListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalerListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AutoscalerStatusDetails struct {
	// Message: The status message.
	Message string `json:"message,omitempty"`

	// Type: The type of error, warning or notice returned. Current set of
	// possible values: ALL_INSTANCES_UNHEALTHY (WARNING): All instances in
	// the instance group are unhealthy (not in RUNNING state).
	// BACKEND_SERVICE_DOES_NOT_EXIST (ERROR): There is no backend service
	// attached to the instance group. CAPPED_AT_MAX_NUM_REPLICAS (WARNING):
	// Autoscaler recommends size bigger than maxNumReplicas.
	// CUSTOM_METRIC_DATA_POINTS_TOO_SPARSE (WARNING): The custom metric
	// samples are not exported often enough to be a credible base for
	// autoscaling. CUSTOM_METRIC_INVALID (ERROR): The custom metric that
	// was specified does not exist or does not have the necessary labels.
	// MIN_EQUALS_MAX (WARNING): The minNumReplicas is equal to
	// maxNumReplicas. This means the autoscaler cannot add or remove
	// instances from the instance group. MISSING_CUSTOM_METRIC_DATA_POINTS
	// (WARNING): The autoscaler did not receive any data from the custom
	// metric configured for autoscaling. MISSING_LOAD_BALANCING_DATA_POINTS
	// (WARNING): The autoscaler is configured to scale based on a load
	// balancing signal but the instance group has not received any requests
	// from the load balancer. MODE_OFF (WARNING): Autoscaling is turned
	// off. The number of instances in the group won't change automatically.
	// The autoscaling configuration is preserved. MODE_ONLY_UP (WARNING):
	// Autoscaling is in the "Autoscale only up" mode. Instances in the
	// group will be only added. MORE_THAN_ONE_BACKEND_SERVICE (ERROR): The
	// instance group cannot be autoscaled because it has more than one
	// backend service attached to it. NOT_ENOUGH_QUOTA_AVAILABLE (ERROR):
	// Exceeded quota for necessary resources, such as CPU, number of
	// instances and so on. REGION_RESOURCE_STOCKOUT (ERROR): Showed only
	// for regional autoscalers: there is a resource stockout in the chosen
	// region. SCALING_TARGET_DOES_NOT_EXIST (ERROR): The target to be
	// scaled does not exist.
	// UNSUPPORTED_MAX_RATE_LOAD_BALANCING_CONFIGURATION (ERROR):
	// Autoscaling does not work with an HTTP/S load balancer that has been
	// configured for maxRate. ZONE_RESOURCE_STOCKOUT (ERROR): For zonal
	// autoscalers: there is a resource stockout in the chosen zone. For
	// regional autoscalers: in at least one of the zones you're using there
	// is a resource stockout. New values might be added in the future. Some
	// of the values might not be available in all API versions.
	//
	// Possible values:
	//   "ALL_INSTANCES_UNHEALTHY"
	//   "BACKEND_SERVICE_DOES_NOT_EXIST"
	//   "CAPPED_AT_MAX_NUM_REPLICAS"
	//   "CUSTOM_METRIC_DATA_POINTS_TOO_SPARSE"
	//   "CUSTOM_METRIC_INVALID"
	//   "MIN_EQUALS_MAX"
	//   "MISSING_CUSTOM_METRIC_DATA_POINTS"
	//   "MISSING_LOAD_BALANCING_DATA_POINTS"
	//   "MODE_OFF"
	//   "MORE_THAN_ONE_BACKEND_SERVICE"
	//   "NOT_ENOUGH_QUOTA_AVAILABLE"
	//   "REGION_RESOURCE_STOCKOUT"
	//   "SCALING_TARGET_DOES_NOT_EXIST"
	//   "UNKNOWN"
	//   "UNSUPPORTED_MAX_RATE_LOAD_BALANCING_CONFIGURATION"
	//   "ZONE_RESOURCE_STOCKOUT"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Message") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Message") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalerStatusDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalerStatusDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AutoscalersScopedList struct {
	// Autoscalers: [Output Only] A list of autoscalers contained in this
	// scope.
	Autoscalers []*Autoscaler `json:"autoscalers,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of autoscalers when the list is empty.
	Warning *AutoscalersScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Autoscalers") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Autoscalers") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalersScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalersScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AutoscalersScopedListWarning: [Output Only] Informational warning
// which replaces the list of autoscalers when the list is empty.
type AutoscalersScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*AutoscalersScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalersScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalersScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type AutoscalersScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalersScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalersScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AutoscalingPolicy: Cloud Autoscaler policy.
type AutoscalingPolicy struct {
	// CoolDownPeriodSec: The number of seconds that the autoscaler should
	// wait before it starts collecting information from a new instance.
	// This prevents the autoscaler from collecting information when the
	// instance is initializing, during which the collected usage would not
	// be reliable. The default time autoscaler waits is 60
	// seconds.
	//
	// Virtual machine initialization times might vary because of numerous
	// factors. We recommend that you test how long an instance may take to
	// initialize. To do this, create an instance and time the startup
	// process.
	CoolDownPeriodSec int64 `json:"coolDownPeriodSec,omitempty"`

	// CpuUtilization: Defines the CPU utilization policy that allows the
	// autoscaler to scale based on the average CPU utilization of a managed
	// instance group.
	CpuUtilization *AutoscalingPolicyCpuUtilization `json:"cpuUtilization,omitempty"`

	// CustomMetricUtilizations: Configuration parameters of autoscaling
	// based on a custom metric.
	CustomMetricUtilizations []*AutoscalingPolicyCustomMetricUtilization `json:"customMetricUtilizations,omitempty"`

	// LoadBalancingUtilization: Configuration parameters of autoscaling
	// based on load balancer.
	LoadBalancingUtilization *AutoscalingPolicyLoadBalancingUtilization `json:"loadBalancingUtilization,omitempty"`

	// MaxNumReplicas: The maximum number of instances that the autoscaler
	// can scale up to. This is required when creating or updating an
	// autoscaler. The maximum number of replicas should not be lower than
	// minimal number of replicas.
	MaxNumReplicas int64 `json:"maxNumReplicas,omitempty"`

	// MinNumReplicas: The minimum number of replicas that the autoscaler
	// can scale down to. This cannot be less than 0. If not provided,
	// autoscaler will choose a default value depending on maximum number of
	// instances allowed.
	MinNumReplicas int64 `json:"minNumReplicas,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CoolDownPeriodSec")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CoolDownPeriodSec") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalingPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalingPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AutoscalingPolicyCpuUtilization: CPU utilization policy.
type AutoscalingPolicyCpuUtilization struct {
	// UtilizationTarget: The target CPU utilization that the autoscaler
	// should maintain. Must be a float value in the range (0, 1]. If not
	// specified, the default is 0.6.
	//
	// If the CPU level is below the target utilization, the autoscaler
	// scales down the number of instances until it reaches the minimum
	// number of instances you specified or until the average CPU of your
	// instances reaches the target utilization.
	//
	// If the average CPU is above the target utilization, the autoscaler
	// scales up until it reaches the maximum number of instances you
	// specified or until the average utilization reaches the target
	// utilization.
	UtilizationTarget float64 `json:"utilizationTarget,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UtilizationTarget")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "UtilizationTarget") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalingPolicyCpuUtilization) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalingPolicyCpuUtilization
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *AutoscalingPolicyCpuUtilization) UnmarshalJSON(data []byte) error {
	type NoMethod AutoscalingPolicyCpuUtilization
	var s1 struct {
		UtilizationTarget gensupport.JSONFloat64 `json:"utilizationTarget"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.UtilizationTarget = float64(s1.UtilizationTarget)
	return nil
}

// AutoscalingPolicyCustomMetricUtilization: Custom utilization metric
// policy.
type AutoscalingPolicyCustomMetricUtilization struct {
	// Metric: The identifier (type) of the Stackdriver Monitoring metric.
	// The metric cannot have negative values.
	//
	// The metric must have a value type of INT64 or DOUBLE.
	Metric string `json:"metric,omitempty"`

	// UtilizationTarget: The target value of the metric that autoscaler
	// should maintain. This must be a positive value. A utilization metric
	// scales number of virtual machines handling requests to increase or
	// decrease proportionally to the metric.
	//
	// For example, a good metric to use as a utilization_target is
	// compute.googleapis.com/instance/network/received_bytes_count. The
	// autoscaler will work to keep this value constant for each of the
	// instances.
	UtilizationTarget float64 `json:"utilizationTarget,omitempty"`

	// UtilizationTargetType: Defines how target utilization value is
	// expressed for a Stackdriver Monitoring metric. Either GAUGE,
	// DELTA_PER_SECOND, or DELTA_PER_MINUTE.
	//
	// Possible values:
	//   "DELTA_PER_MINUTE"
	//   "DELTA_PER_SECOND"
	//   "GAUGE"
	UtilizationTargetType string `json:"utilizationTargetType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Metric") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Metric") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalingPolicyCustomMetricUtilization) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalingPolicyCustomMetricUtilization
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *AutoscalingPolicyCustomMetricUtilization) UnmarshalJSON(data []byte) error {
	type NoMethod AutoscalingPolicyCustomMetricUtilization
	var s1 struct {
		UtilizationTarget gensupport.JSONFloat64 `json:"utilizationTarget"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.UtilizationTarget = float64(s1.UtilizationTarget)
	return nil
}

// AutoscalingPolicyLoadBalancingUtilization: Configuration parameters
// of autoscaling based on load balancing.
type AutoscalingPolicyLoadBalancingUtilization struct {
	// UtilizationTarget: Fraction of backend capacity utilization (set in
	// HTTP(S) load balancing configuration) that autoscaler should
	// maintain. Must be a positive float value. If not defined, the default
	// is 0.8.
	UtilizationTarget float64 `json:"utilizationTarget,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UtilizationTarget")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "UtilizationTarget") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AutoscalingPolicyLoadBalancingUtilization) MarshalJSON() ([]byte, error) {
	type NoMethod AutoscalingPolicyLoadBalancingUtilization
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *AutoscalingPolicyLoadBalancingUtilization) UnmarshalJSON(data []byte) error {
	type NoMethod AutoscalingPolicyLoadBalancingUtilization
	var s1 struct {
		UtilizationTarget gensupport.JSONFloat64 `json:"utilizationTarget"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.UtilizationTarget = float64(s1.UtilizationTarget)
	return nil
}

// Backend: Message containing information of one individual backend.
type Backend struct {
	// BalancingMode: Specifies the balancing mode for the backend.
	//
	// When choosing a balancing mode, you need to consider the
	// loadBalancingScheme, and protocol for the backend service, as well as
	// the type of backend (instance group or NEG).
	//
	//
	// - If the load balancing mode is CONNECTION, then the load is spread
	// based on how many concurrent connections the backend can handle.
	// You can use the CONNECTION balancing mode if the protocol for the
	// backend service is SSL, TCP, or UDP.
	//
	// If the loadBalancingScheme for the backend service is EXTERNAL (SSL
	// Proxy and TCP Proxy load balancers), you must also specify exactly
	// one of the following parameters: maxConnections,
	// maxConnectionsPerInstance, or maxConnectionsPerEndpoint.
	//
	// If the loadBalancingScheme for the backend service is INTERNAL
	// (internal TCP/UDP load balancers), you cannot specify any additional
	// parameters.
	//
	// - If the load balancing mode is RATE, the load is spread based on the
	// rate of HTTP requests per second (RPS).
	// You can use the RATE balancing mode if the protocol for the backend
	// service is HTTP or HTTPS. You must specify exactly one of the
	// following parameters: maxRate, maxRatePerInstance, or
	// maxRatePerEndpoint.
	//
	// - If the load balancing mode is UTILIZATION, the load is spread based
	// on the CPU utilization of instances in an instance group.
	// You can use the UTILIZATION balancing mode if the loadBalancingScheme
	// of the backend service is EXTERNAL, INTERNAL_SELF_MANAGED, or
	// INTERNAL_MANAGED and the backends are instance groups. There are no
	// restrictions on the backend service protocol.
	//
	// Possible values:
	//   "CONNECTION"
	//   "RATE"
	//   "UTILIZATION"
	BalancingMode string `json:"balancingMode,omitempty"`

	// CapacityScaler: A multiplier applied to the group's maximum servicing
	// capacity (based on UTILIZATION, RATE or CONNECTION). Default value is
	// 1, which means the group will serve up to 100% of its configured
	// capacity (depending on balancingMode). A setting of 0 means the group
	// is completely drained, offering 0% of its available Capacity. Valid
	// range is [0.0,1.0].
	//
	// This cannot be used for internal load balancing.
	CapacityScaler float64 `json:"capacityScaler,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Group: The fully-qualified URL of an instance group or network
	// endpoint group (NEG) resource. The type of backend that a backend
	// service supports depends on the backend service's
	// loadBalancingScheme.
	//
	//
	// - When the loadBalancingScheme for the backend service is EXTERNAL,
	// INTERNAL_SELF_MANAGED, or INTERNAL_MANAGED, the backend can be either
	// an instance group or a NEG. The backends on the backend service must
	// be either all instance groups or all NEGs. You cannot mix instance
	// group and NEG backends on the same backend service.
	//
	//
	// - When the loadBalancingScheme for the backend service is INTERNAL,
	// the backend must be an instance group in the same region as the
	// backend service. NEGs are not supported.
	//
	// You must use the fully-qualified URL (starting with
	// https://www.googleapis.com/) to specify the instance group or NEG.
	// Partial URLs are not supported.
	Group string `json:"group,omitempty"`

	// MaxConnections: Defines a maximum target for simultaneous connections
	// for the entire backend (instance group or NEG). If the backend's
	// balancingMode is UTILIZATION, this is an optional parameter. If the
	// backend's balancingMode is CONNECTION, and backend is attached to a
	// backend service whose loadBalancingScheme is EXTERNAL, you must
	// specify either this parameter, maxConnectionsPerInstance, or
	// maxConnectionsPerEndpoint.
	//
	// Not available if the backend's balancingMode is RATE. If the
	// loadBalancingScheme is INTERNAL, then maxConnections is not
	// supported, even though the backend requires a balancing mode of
	// CONNECTION.
	MaxConnections int64 `json:"maxConnections,omitempty"`

	// MaxConnectionsPerEndpoint: Defines a maximum target for simultaneous
	// connections for an endpoint of a NEG. This is multiplied by the
	// number of endpoints in the NEG to implicitly calculate a maximum
	// number of target maximum simultaneous connections for the NEG. If the
	// backend's balancingMode is CONNECTION, and the backend is attached to
	// a backend service whose loadBalancingScheme is EXTERNAL, you must
	// specify either this parameter, maxConnections, or
	// maxConnectionsPerInstance.
	//
	// Not available if the backend's balancingMode is RATE. Internal
	// TCP/UDP load balancing does not support setting
	// maxConnectionsPerEndpoint even though its backends require a
	// balancing mode of CONNECTION.
	MaxConnectionsPerEndpoint int64 `json:"maxConnectionsPerEndpoint,omitempty"`

	// MaxConnectionsPerInstance: Defines a maximum target for simultaneous
	// connections for a single VM in a backend instance group. This is
	// multiplied by the number of instances in the instance group to
	// implicitly calculate a target maximum number of simultaneous
	// connections for the whole instance group. If the backend's
	// balancingMode is UTILIZATION, this is an optional parameter. If the
	// backend's balancingMode is CONNECTION, and backend is attached to a
	// backend service whose loadBalancingScheme is EXTERNAL, you must
	// specify either this parameter, maxConnections, or
	// maxConnectionsPerEndpoint.
	//
	// Not available if the backend's balancingMode is RATE. Internal
	// TCP/UDP load balancing does not support setting
	// maxConnectionsPerInstance even though its backends require a
	// balancing mode of CONNECTION.
	MaxConnectionsPerInstance int64 `json:"maxConnectionsPerInstance,omitempty"`

	// MaxRate: The max requests per second (RPS) of the group. Can be used
	// with either RATE or UTILIZATION balancing modes, but required if RATE
	// mode. For RATE mode, either maxRate or maxRatePerInstance must be
	// set.
	//
	// This cannot be used for internal load balancing.
	MaxRate int64 `json:"maxRate,omitempty"`

	// MaxRatePerEndpoint: Defines a maximum target for requests per second
	// (RPS) for an endpoint of a NEG. This is multiplied by the number of
	// endpoints in the NEG to implicitly calculate a target maximum rate
	// for the NEG.
	//
	// If the backend's balancingMode is RATE, you must specify either this
	// parameter, maxRate, or maxRatePerInstance.
	//
	// Not available if the backend's balancingMode is CONNECTION.
	MaxRatePerEndpoint float64 `json:"maxRatePerEndpoint,omitempty"`

	// MaxRatePerInstance: Defines a maximum target for requests per second
	// (RPS) for a single VM in a backend instance group. This is multiplied
	// by the number of instances in the instance group to implicitly
	// calculate a target maximum rate for the whole instance group.
	//
	// If the backend's balancingMode is UTILIZATION, this is an optional
	// parameter. If the backend's balancingMode is RATE, you must specify
	// either this parameter, maxRate, or maxRatePerEndpoint.
	//
	// Not available if the backend's balancingMode is CONNECTION.
	MaxRatePerInstance float64 `json:"maxRatePerInstance,omitempty"`

	// MaxUtilization: Defines the maximum average CPU utilization of a
	// backend VM in an instance group. The valid range is [0.0, 1.0]. This
	// is an optional parameter if the backend's balancingMode is
	// UTILIZATION.
	//
	// This parameter can be used in conjunction with maxRate,
	// maxRatePerInstance, maxConnections, or maxConnectionsPerInstance.
	MaxUtilization float64 `json:"maxUtilization,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BalancingMode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BalancingMode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Backend) MarshalJSON() ([]byte, error) {
	type NoMethod Backend
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Backend) UnmarshalJSON(data []byte) error {
	type NoMethod Backend
	var s1 struct {
		CapacityScaler     gensupport.JSONFloat64 `json:"capacityScaler"`
		MaxRatePerEndpoint gensupport.JSONFloat64 `json:"maxRatePerEndpoint"`
		MaxRatePerInstance gensupport.JSONFloat64 `json:"maxRatePerInstance"`
		MaxUtilization     gensupport.JSONFloat64 `json:"maxUtilization"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.CapacityScaler = float64(s1.CapacityScaler)
	s.MaxRatePerEndpoint = float64(s1.MaxRatePerEndpoint)
	s.MaxRatePerInstance = float64(s1.MaxRatePerInstance)
	s.MaxUtilization = float64(s1.MaxUtilization)
	return nil
}

// BackendBucket: Represents a Cloud Storage Bucket resource.
//
// This Cloud Storage bucket resource is referenced by a URL map of a
// load balancer. For more information, read Backend Buckets.
type BackendBucket struct {
	// BucketName: Cloud Storage bucket name.
	BucketName string `json:"bucketName,omitempty"`

	// CdnPolicy: Cloud CDN configuration for this BackendBucket.
	CdnPolicy *BackendBucketCdnPolicy `json:"cdnPolicy,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional textual description of the resource;
	// provided by the client when the resource is created.
	Description string `json:"description,omitempty"`

	// EnableCdn: If true, enable Cloud CDN for this BackendBucket.
	EnableCdn bool `json:"enableCdn,omitempty"`

	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: Type of the resource.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "BucketName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BucketName") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendBucket) MarshalJSON() ([]byte, error) {
	type NoMethod BackendBucket
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendBucketCdnPolicy: Message containing Cloud CDN configuration
// for a backend bucket.
type BackendBucketCdnPolicy struct {
	// SignedUrlCacheMaxAgeSec: Maximum number of seconds the response to a
	// signed URL request will be considered fresh. After this time period,
	// the response will be revalidated before being served. Defaults to 1hr
	// (3600s). When serving responses to signed URL requests, Cloud CDN
	// will internally behave as though all responses from this backend had
	// a "Cache-Control: public, max-age=[TTL]" header, regardless of any
	// existing Cache-Control header. The actual headers served in responses
	// will not be altered.
	SignedUrlCacheMaxAgeSec int64 `json:"signedUrlCacheMaxAgeSec,omitempty,string"`

	// SignedUrlKeyNames: [Output Only] Names of the keys for signing
	// request URLs.
	SignedUrlKeyNames []string `json:"signedUrlKeyNames,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "SignedUrlCacheMaxAgeSec") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SignedUrlCacheMaxAgeSec")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *BackendBucketCdnPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod BackendBucketCdnPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendBucketList: Contains a list of BackendBucket resources.
type BackendBucketList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of BackendBucket resources.
	Items []*BackendBucket `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *BackendBucketListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendBucketList) MarshalJSON() ([]byte, error) {
	type NoMethod BackendBucketList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendBucketListWarning: [Output Only] Informational warning
// message.
type BackendBucketListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*BackendBucketListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendBucketListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod BackendBucketListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BackendBucketListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendBucketListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod BackendBucketListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendService: Represents a Backend Service resource.
//
// A backend service contains configuration values for Google Cloud
// Platform load balancing services.
//
// For more information, read Backend Services.
//
// (== resource_for v1.backendService ==) (== resource_for
// beta.backendService ==)
type BackendService struct {
	// AffinityCookieTtlSec: If set to 0, the cookie is non-persistent and
	// lasts only until the end of the browser session (or equivalent). The
	// maximum allowed value is one day (86,400).
	AffinityCookieTtlSec int64 `json:"affinityCookieTtlSec,omitempty"`

	// Backends: The list of backends that serve this BackendService.
	Backends []*Backend `json:"backends,omitempty"`

	// CdnPolicy: Cloud CDN configuration for this BackendService.
	CdnPolicy *BackendServiceCdnPolicy `json:"cdnPolicy,omitempty"`

	// CircuitBreakers: Settings controlling the volume of connections to a
	// backend service. If not set, this feature is considered
	// disabled.
	//
	// This field is applicable to either:
	// - A regional backend service with the service_protocol set to HTTP,
	// HTTPS, or HTTP2, and load_balancing_scheme set to INTERNAL_MANAGED.
	//
	// - A global backend service with the load_balancing_scheme set to
	// INTERNAL_SELF_MANAGED.
	CircuitBreakers *CircuitBreakers `json:"circuitBreakers,omitempty"`

	ConnectionDraining *ConnectionDraining `json:"connectionDraining,omitempty"`

	// ConsistentHash: Consistent Hash-based load balancing can be used to
	// provide soft session affinity based on HTTP headers, cookies or other
	// properties. This load balancing policy is applicable only for HTTP
	// connections. The affinity to a particular destination host will be
	// lost when one or more hosts are added/removed from the destination
	// service. This field specifies parameters that control consistent
	// hashing. This field is only applicable when localityLbPolicy is set
	// to MAGLEV or RING_HASH.
	//
	// This field is applicable to either:
	// - A regional backend service with the service_protocol set to HTTP,
	// HTTPS, or HTTP2, and load_balancing_scheme set to INTERNAL_MANAGED.
	//
	// - A global backend service with the load_balancing_scheme set to
	// INTERNAL_SELF_MANAGED.
	ConsistentHash *ConsistentHashLoadBalancerSettings `json:"consistentHash,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// CustomRequestHeaders: Headers that the HTTP/S load balancer should
	// add to proxied requests.
	CustomRequestHeaders []string `json:"customRequestHeaders,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// EnableCDN: If true, enables Cloud CDN for the backend service. Only
	// applicable if the loadBalancingScheme is EXTERNAL and the protocol is
	// HTTP or HTTPS.
	EnableCDN bool `json:"enableCDN,omitempty"`

	// Fingerprint: Fingerprint of this resource. A hash of the contents
	// stored in this object. This field is used in optimistic locking. This
	// field will be ignored when inserting a BackendService. An up-to-date
	// fingerprint must be provided in order to update the BackendService,
	// otherwise the request will fail with error 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve a
	// BackendService.
	Fingerprint string `json:"fingerprint,omitempty"`

	// HealthChecks: The list of URLs to the HttpHealthCheck or
	// HttpsHealthCheck resource for health checking this BackendService.
	// Currently at most one health check can be specified, and a health
	// check is required for Compute Engine backend services. A health check
	// must not be specified for App Engine backend and Cloud Function
	// backend.
	//
	// For internal load balancing, a URL to a HealthCheck resource must be
	// specified instead.
	HealthChecks []string `json:"healthChecks,omitempty"`

	Iap *BackendServiceIAP `json:"iap,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of resource. Always compute#backendService
	// for backend services.
	Kind string `json:"kind,omitempty"`

	// LoadBalancingScheme: Specifies the load balancer type. Choose
	// EXTERNAL for load balancers that receive traffic from external
	// clients. Choose INTERNAL for Internal TCP/UDP Load Balancing. Choose
	// INTERNAL_MANAGED for Internal HTTP(S) Load Balancing. Choose
	// INTERNAL_SELF_MANAGED for Traffic Director. A backend service created
	// for one type of load balancing cannot be used with another. For more
	// information, refer to Choosing a load balancer.
	//
	// Possible values:
	//   "EXTERNAL"
	//   "INTERNAL"
	//   "INTERNAL_MANAGED"
	//   "INTERNAL_SELF_MANAGED"
	//   "INVALID_LOAD_BALANCING_SCHEME"
	LoadBalancingScheme string `json:"loadBalancingScheme,omitempty"`

	// LocalityLbPolicy: The load balancing algorithm used within the scope
	// of the locality. The possible values are:
	// - ROUND_ROBIN: This is a simple policy in which each healthy backend
	// is selected in round robin order. This is the default.
	// - LEAST_REQUEST: An O(1) algorithm which selects two random healthy
	// hosts and picks the host which has fewer active requests.
	// - RING_HASH: The ring/modulo hash load balancer implements consistent
	// hashing to backends. The algorithm has the property that the
	// addition/removal of a host from a set of N hosts only affects 1/N of
	// the requests.
	// - RANDOM: The load balancer selects a random healthy host.
	// - ORIGINAL_DESTINATION: Backend host is selected based on the client
	// connection metadata, i.e., connections are opened to the same address
	// as the destination address of the incoming connection before the
	// connection was redirected to the load balancer.
	// - MAGLEV: used as a drop in replacement for the ring hash load
	// balancer. Maglev is not as stable as ring hash but has faster table
	// lookup build times and host selection times. For more information
	// about Maglev, refer to https://ai.google/research/pubs/pub44824
	//
	//
	// This field is applicable to either:
	// - A regional backend service with the service_protocol set to HTTP,
	// HTTPS, or HTTP2, and load_balancing_scheme set to INTERNAL_MANAGED.
	//
	// - A global backend service with the load_balancing_scheme set to
	// INTERNAL_SELF_MANAGED.
	//
	// Possible values:
	//   "INVALID_LB_POLICY"
	//   "LEAST_REQUEST"
	//   "MAGLEV"
	//   "ORIGINAL_DESTINATION"
	//   "RANDOM"
	//   "RING_HASH"
	//   "ROUND_ROBIN"
	LocalityLbPolicy string `json:"localityLbPolicy,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// OutlierDetection: Settings controlling the eviction of unhealthy
	// hosts from the load balancing pool for the backend service. If not
	// set, this feature is considered disabled.
	//
	// This field is applicable to either:
	// - A regional backend service with the service_protocol set to HTTP,
	// HTTPS, or HTTP2, and load_balancing_scheme set to INTERNAL_MANAGED.
	//
	// - A global backend service with the load_balancing_scheme set to
	// INTERNAL_SELF_MANAGED.
	OutlierDetection *OutlierDetection `json:"outlierDetection,omitempty"`

	// Port: Deprecated in favor of portName. The TCP port to connect on the
	// backend. The default value is 80.
	//
	// This cannot be used if the loadBalancingScheme is INTERNAL (Internal
	// TCP/UDP Load Balancing).
	Port int64 `json:"port,omitempty"`

	// PortName: A named port on a backend instance group representing the
	// port for communication to the backend VMs in that group. Required
	// when the loadBalancingScheme is EXTERNAL and the backends are
	// instance groups. The named port must be defined on each backend
	// instance group. This parameter has no meaning if the backends are
	// NEGs.
	//
	//
	//
	// Must be omitted when the loadBalancingScheme is INTERNAL (Internal
	// TCP/UDP Load Blaancing).
	PortName string `json:"portName,omitempty"`

	// Protocol: The protocol this BackendService uses to communicate with
	// backends.
	//
	// Possible values are HTTP, HTTPS, HTTP2, TCP, SSL, or UDP, depending
	// on the chosen load balancer or Traffic Director configuration. Refer
	// to the documentation for the load balancer or for Traffic Director
	// for more information.
	//
	// Possible values:
	//   "HTTP"
	//   "HTTP2"
	//   "HTTPS"
	//   "SSL"
	//   "TCP"
	//   "UDP"
	Protocol string `json:"protocol,omitempty"`

	// Region: [Output Only] URL of the region where the regional backend
	// service resides. This field is not applicable to global backend
	// services. You must specify this field as part of the HTTP request
	// URL. It is not settable as a field in the request body.
	Region string `json:"region,omitempty"`

	// SecurityPolicy: [Output Only] The resource URL for the security
	// policy associated with this backend service.
	SecurityPolicy string `json:"securityPolicy,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SessionAffinity: Type of session affinity to use. The default is
	// NONE. Session affinity is not applicable if the --protocol is
	// UDP.
	//
	// When the loadBalancingScheme is EXTERNAL, possible values are NONE,
	// CLIENT_IP, or GENERATED_COOKIE. You can use GENERATED_COOKIE if the
	// protocol is HTTP or HTTPS.
	//
	// When the loadBalancingScheme is INTERNAL, possible values are NONE,
	// CLIENT_IP, CLIENT_IP_PROTO, or CLIENT_IP_PORT_PROTO.
	//
	// When the loadBalancingScheme is INTERNAL_SELF_MANAGED, possible
	// values are NONE, CLIENT_IP, GENERATED_COOKIE, HEADER_FIELD, or
	// HTTP_COOKIE.
	//
	// Possible values:
	//   "CLIENT_IP"
	//   "CLIENT_IP_PORT_PROTO"
	//   "CLIENT_IP_PROTO"
	//   "GENERATED_COOKIE"
	//   "HEADER_FIELD"
	//   "HTTP_COOKIE"
	//   "NONE"
	SessionAffinity string `json:"sessionAffinity,omitempty"`

	// TimeoutSec: The backend service timeout has a different meaning
	// depending on the type of load balancer. For more information read,
	// Backend service settings The default is 30 seconds.
	TimeoutSec int64 `json:"timeoutSec,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "AffinityCookieTtlSec") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AffinityCookieTtlSec") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *BackendService) MarshalJSON() ([]byte, error) {
	type NoMethod BackendService
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendServiceAggregatedList: Contains a list of
// BackendServicesScopedList.
type BackendServiceAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of BackendServicesScopedList resources.
	Items map[string]BackendServicesScopedList `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *BackendServiceAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendServiceAggregatedListWarning: [Output Only] Informational
// warning message.
type BackendServiceAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*BackendServiceAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BackendServiceAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendServiceCdnPolicy: Message containing Cloud CDN configuration
// for a backend service.
type BackendServiceCdnPolicy struct {
	// CacheKeyPolicy: The CacheKeyPolicy for this CdnPolicy.
	CacheKeyPolicy *CacheKeyPolicy `json:"cacheKeyPolicy,omitempty"`

	// SignedUrlCacheMaxAgeSec: Maximum number of seconds the response to a
	// signed URL request will be considered fresh. After this time period,
	// the response will be revalidated before being served. Defaults to 1hr
	// (3600s). When serving responses to signed URL requests, Cloud CDN
	// will internally behave as though all responses from this backend had
	// a "Cache-Control: public, max-age=[TTL]" header, regardless of any
	// existing Cache-Control header. The actual headers served in responses
	// will not be altered.
	SignedUrlCacheMaxAgeSec int64 `json:"signedUrlCacheMaxAgeSec,omitempty,string"`

	// SignedUrlKeyNames: [Output Only] Names of the keys for signing
	// request URLs.
	SignedUrlKeyNames []string `json:"signedUrlKeyNames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CacheKeyPolicy") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CacheKeyPolicy") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceCdnPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceCdnPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BackendServiceGroupHealth struct {
	// HealthStatus: Health state of the backend instances or endpoints in
	// requested instance or network endpoint group, determined based on
	// configured health checks.
	HealthStatus []*HealthStatus `json:"healthStatus,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#backendServiceGroupHealth for the health of backend services.
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "HealthStatus") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthStatus") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceGroupHealth) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceGroupHealth
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendServiceIAP: Identity-Aware Proxy
type BackendServiceIAP struct {
	Enabled bool `json:"enabled,omitempty"`

	Oauth2ClientId string `json:"oauth2ClientId,omitempty"`

	Oauth2ClientSecret string `json:"oauth2ClientSecret,omitempty"`

	// Oauth2ClientSecretSha256: [Output Only] SHA256 hash value for the
	// field oauth2_client_secret above.
	Oauth2ClientSecretSha256 string `json:"oauth2ClientSecretSha256,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Enabled") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Enabled") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceIAP) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceIAP
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendServiceList: Contains a list of BackendService resources.
type BackendServiceList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of BackendService resources.
	Items []*BackendService `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#backendServiceList for lists of backend services.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *BackendServiceListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceList) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendServiceListWarning: [Output Only] Informational warning
// message.
type BackendServiceListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*BackendServiceListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BackendServiceListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BackendServiceReference struct {
	BackendService string `json:"backendService,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackendService") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackendService") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *BackendServiceReference) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServiceReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BackendServicesScopedList struct {
	// BackendServices: A list of BackendServices contained in this scope.
	BackendServices []*BackendService `json:"backendServices,omitempty"`

	// Warning: Informational warning which replaces the list of backend
	// services when the list is empty.
	Warning *BackendServicesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackendServices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackendServices") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *BackendServicesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServicesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackendServicesScopedListWarning: Informational warning which
// replaces the list of backend services when the list is empty.
type BackendServicesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*BackendServicesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServicesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServicesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BackendServicesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BackendServicesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod BackendServicesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Binding: Associates `members` with a `role`.
type Binding struct {
	// Condition: The condition that is associated with this binding. NOTE:
	// An unsatisfied condition will not allow user access via current
	// binding. Different bindings, including their conditions, are examined
	// independently.
	Condition *Expr `json:"condition,omitempty"`

	// Members: Specifies the identities requesting access for a Cloud
	// Platform resource. `members` can have the following values:
	//
	// * `allUsers`: A special identifier that represents anyone who is on
	// the internet; with or without a Google account.
	//
	// * `allAuthenticatedUsers`: A special identifier that represents
	// anyone who is authenticated with a Google account or a service
	// account.
	//
	// * `user:{emailid}`: An email address that represents a specific
	// Google account. For example, `alice@example.com` .
	//
	//
	//
	// * `serviceAccount:{emailid}`: An email address that represents a
	// service account. For example,
	// `my-other-app@appspot.gserviceaccount.com`.
	//
	// * `group:{emailid}`: An email address that represents a Google group.
	// For example, `admins@example.com`.
	//
	//
	//
	// * `domain:{domain}`: The G Suite domain (primary) that represents all
	// the users of that domain. For example, `google.com` or `example.com`.
	Members []string `json:"members,omitempty"`

	// Role: Role that is assigned to `members`. For example,
	// `roles/viewer`, `roles/editor`, or `roles/owner`.
	Role string `json:"role,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Condition") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Condition") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Binding) MarshalJSON() ([]byte, error) {
	type NoMethod Binding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type CacheInvalidationRule struct {
	// Host: If set, this invalidation rule will only apply to requests with
	// a Host header matching host.
	Host string `json:"host,omitempty"`

	Path string `json:"path,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Host") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Host") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CacheInvalidationRule) MarshalJSON() ([]byte, error) {
	type NoMethod CacheInvalidationRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CacheKeyPolicy: Message containing what to include in the cache key
// for a request for Cloud CDN.
type CacheKeyPolicy struct {
	// IncludeHost: If true, requests to different hosts will be cached
	// separately.
	IncludeHost bool `json:"includeHost,omitempty"`

	// IncludeProtocol: If true, http and https requests will be cached
	// separately.
	IncludeProtocol bool `json:"includeProtocol,omitempty"`

	// IncludeQueryString: If true, include query string parameters in the
	// cache key according to query_string_whitelist and
	// query_string_blacklist. If neither is set, the entire query string
	// will be included. If false, the query string will be excluded from
	// the cache key entirely.
	IncludeQueryString bool `json:"includeQueryString,omitempty"`

	// QueryStringBlacklist: Names of query string parameters to exclude in
	// cache keys. All other parameters will be included. Either specify
	// query_string_whitelist or query_string_blacklist, not both. '&' and
	// '=' will be percent encoded and not treated as delimiters.
	QueryStringBlacklist []string `json:"queryStringBlacklist,omitempty"`

	// QueryStringWhitelist: Names of query string parameters to include in
	// cache keys. All other parameters will be excluded. Either specify
	// query_string_whitelist or query_string_blacklist, not both. '&' and
	// '=' will be percent encoded and not treated as delimiters.
	QueryStringWhitelist []string `json:"queryStringWhitelist,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IncludeHost") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IncludeHost") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CacheKeyPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod CacheKeyPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CircuitBreakers: Settings controlling the volume of connections to a
// backend service.
type CircuitBreakers struct {
	// MaxConnections: The maximum number of connections to the backend
	// service. If not specified, there is no limit.
	MaxConnections int64 `json:"maxConnections,omitempty"`

	// MaxPendingRequests: The maximum number of pending requests allowed to
	// the backend service. If not specified, there is no limit.
	MaxPendingRequests int64 `json:"maxPendingRequests,omitempty"`

	// MaxRequests: The maximum number of parallel requests that allowed to
	// the backend service. If not specified, there is no limit.
	MaxRequests int64 `json:"maxRequests,omitempty"`

	// MaxRequestsPerConnection: Maximum requests for a single connection to
	// the backend service. This parameter is respected by both the HTTP/1.1
	// and HTTP/2 implementations. If not specified, there is no limit.
	// Setting this parameter to 1 will effectively disable keep alive.
	MaxRequestsPerConnection int64 `json:"maxRequestsPerConnection,omitempty"`

	// MaxRetries: The maximum number of parallel retries allowed to the
	// backend cluster. If not specified, the default is 1.
	MaxRetries int64 `json:"maxRetries,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MaxConnections") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MaxConnections") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CircuitBreakers) MarshalJSON() ([]byte, error) {
	type NoMethod CircuitBreakers
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Commitment: Represents a regional Commitment resource.
//
// Creating a commitment resource means that you are purchasing a
// committed use contract with an explicit start and end time. You can
// create commitments based on vCPUs and memory usage and receive
// discounted rates. For full details, read Signing Up for Committed Use
// Discounts. (== resource_for beta.regionCommitments ==) (==
// resource_for v1.regionCommitments ==)
type Commitment struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// EndTimestamp: [Output Only] Commitment end time in RFC3339 text
	// format.
	EndTimestamp string `json:"endTimestamp,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#commitment
	// for commitments.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Plan: The plan for this commitment, which determines duration and
	// discount rate. The currently supported plans are TWELVE_MONTH (1
	// year), and THIRTY_SIX_MONTH (3 years).
	//
	// Possible values:
	//   "INVALID"
	//   "THIRTY_SIX_MONTH"
	//   "TWELVE_MONTH"
	Plan string `json:"plan,omitempty"`

	// Region: [Output Only] URL of the region where this commitment may be
	// used.
	Region string `json:"region,omitempty"`

	// Reservations: List of reservations in this commitment.
	Reservations []*Reservation `json:"reservations,omitempty"`

	// Resources: A list of commitment amounts for particular resources.
	// Note that VCPU and MEMORY resource commitments must occur together.
	Resources []*ResourceCommitment `json:"resources,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// StartTimestamp: [Output Only] Commitment start time in RFC3339 text
	// format.
	StartTimestamp string `json:"startTimestamp,omitempty"`

	// Status: [Output Only] Status of the commitment with regards to
	// eventual expiration (each commitment has an end date defined). One of
	// the following values: NOT_YET_ACTIVE, ACTIVE, EXPIRED.
	//
	// Possible values:
	//   "ACTIVE"
	//   "CREATING"
	//   "EXPIRED"
	//   "NOT_YET_ACTIVE"
	Status string `json:"status,omitempty"`

	// StatusMessage: [Output Only] An optional, human-readable explanation
	// of the status.
	StatusMessage string `json:"statusMessage,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Commitment) MarshalJSON() ([]byte, error) {
	type NoMethod Commitment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type CommitmentAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of CommitmentsScopedList resources.
	Items map[string]CommitmentsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#commitmentAggregatedList for aggregated lists of commitments.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *CommitmentAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CommitmentAggregatedListWarning: [Output Only] Informational warning
// message.
type CommitmentAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*CommitmentAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type CommitmentAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CommitmentList: Contains a list of Commitment resources.
type CommitmentList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Commitment resources.
	Items []*Commitment `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#commitmentList
	// for lists of commitments.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *CommitmentListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentList) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CommitmentListWarning: [Output Only] Informational warning message.
type CommitmentListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*CommitmentListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type CommitmentListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type CommitmentsScopedList struct {
	// Commitments: [Output Only] A list of commitments contained in this
	// scope.
	Commitments []*Commitment `json:"commitments,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of commitments when the list is empty.
	Warning *CommitmentsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Commitments") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Commitments") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CommitmentsScopedListWarning: [Output Only] Informational warning
// which replaces the list of commitments when the list is empty.
type CommitmentsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*CommitmentsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type CommitmentsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CommitmentsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod CommitmentsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Condition: A condition to be met.
type Condition struct {
	// Iam: Trusted attributes supplied by the IAM system.
	//
	// Possible values:
	//   "APPROVER"
	//   "ATTRIBUTION"
	//   "AUTHORITY"
	//   "CREDENTIALS_TYPE"
	//   "JUSTIFICATION_TYPE"
	//   "NO_ATTR"
	//   "SECURITY_REALM"
	Iam string `json:"iam,omitempty"`

	// Op: An operator to apply the subject with.
	//
	// Possible values:
	//   "DISCHARGED"
	//   "EQUALS"
	//   "IN"
	//   "NOT_EQUALS"
	//   "NOT_IN"
	//   "NO_OP"
	Op string `json:"op,omitempty"`

	// Svc: Trusted attributes discharged by the service.
	Svc string `json:"svc,omitempty"`

	// Sys: Trusted attributes supplied by any service that owns resources
	// and uses the IAM system for access control.
	//
	// Possible values:
	//   "IP"
	//   "NAME"
	//   "NO_ATTR"
	//   "REGION"
	//   "SERVICE"
	Sys string `json:"sys,omitempty"`

	// Values: The objects of the condition.
	Values []string `json:"values,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Iam") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Iam") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Condition) MarshalJSON() ([]byte, error) {
	type NoMethod Condition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ConnectionDraining: Message containing connection draining
// configuration.
type ConnectionDraining struct {
	// DrainingTimeoutSec: The amount of time in seconds to allow existing
	// connections to persist while on unhealthy backend VMs. Only
	// applicable if the protocol is not UDP. The valid range is [0, 3600].
	DrainingTimeoutSec int64 `json:"drainingTimeoutSec,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DrainingTimeoutSec")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DrainingTimeoutSec") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ConnectionDraining) MarshalJSON() ([]byte, error) {
	type NoMethod ConnectionDraining
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ConsistentHashLoadBalancerSettings: This message defines settings for
// a consistent hash style load balancer.
type ConsistentHashLoadBalancerSettings struct {
	// HttpCookie: Hash is based on HTTP Cookie. This field describes a HTTP
	// cookie that will be used as the hash key for the consistent hash load
	// balancer. If the cookie is not present, it will be generated. This
	// field is applicable if the sessionAffinity is set to HTTP_COOKIE.
	HttpCookie *ConsistentHashLoadBalancerSettingsHttpCookie `json:"httpCookie,omitempty"`

	// HttpHeaderName: The hash based on the value of the specified header
	// field. This field is applicable if the sessionAffinity is set to
	// HEADER_FIELD.
	HttpHeaderName string `json:"httpHeaderName,omitempty"`

	// MinimumRingSize: The minimum number of virtual nodes to use for the
	// hash ring. Defaults to 1024. Larger ring sizes result in more
	// granular load distributions. If the number of hosts in the load
	// balancing pool is larger than the ring size, each host will be
	// assigned a single virtual node.
	MinimumRingSize int64 `json:"minimumRingSize,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "HttpCookie") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HttpCookie") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ConsistentHashLoadBalancerSettings) MarshalJSON() ([]byte, error) {
	type NoMethod ConsistentHashLoadBalancerSettings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ConsistentHashLoadBalancerSettingsHttpCookie: The information about
// the HTTP Cookie on which the hash function is based for load
// balancing policies that use a consistent hash.
type ConsistentHashLoadBalancerSettingsHttpCookie struct {
	// Name: Name of the cookie.
	Name string `json:"name,omitempty"`

	// Path: Path to set for the cookie.
	Path string `json:"path,omitempty"`

	// Ttl: Lifetime of the cookie.
	Ttl *Duration `json:"ttl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ConsistentHashLoadBalancerSettingsHttpCookie) MarshalJSON() ([]byte, error) {
	type NoMethod ConsistentHashLoadBalancerSettingsHttpCookie
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CorsPolicy: The specification for allowing client side cross-origin
// requests. Please see W3C Recommendation for Cross Origin Resource
// Sharing
type CorsPolicy struct {
	// AllowCredentials: In response to a preflight request, setting this to
	// true indicates that the actual request can include user credentials.
	// This translates to the Access-Control-Allow-Credentials
	// header.
	// Default is false.
	AllowCredentials bool `json:"allowCredentials,omitempty"`

	// AllowHeaders: Specifies the content for the
	// Access-Control-Allow-Headers header.
	AllowHeaders []string `json:"allowHeaders,omitempty"`

	// AllowMethods: Specifies the content for the
	// Access-Control-Allow-Methods header.
	AllowMethods []string `json:"allowMethods,omitempty"`

	// AllowOriginRegexes: Specifies the regualar expression patterns that
	// match allowed origins. For regular expression grammar please see
	// en.cppreference.com/w/cpp/regex/ecmascript
	// An origin is allowed if it matches either allow_origins or
	// allow_origin_regex.
	AllowOriginRegexes []string `json:"allowOriginRegexes,omitempty"`

	// AllowOrigins: Specifies the list of origins that will be allowed to
	// do CORS requests.
	// An origin is allowed if it matches either allow_origins or
	// allow_origin_regex.
	AllowOrigins []string `json:"allowOrigins,omitempty"`

	// Disabled: If true, specifies the CORS policy is disabled. The default
	// value of false, which indicates that the CORS policy is in effect.
	Disabled bool `json:"disabled,omitempty"`

	// ExposeHeaders: Specifies the content for the
	// Access-Control-Expose-Headers header.
	ExposeHeaders []string `json:"exposeHeaders,omitempty"`

	// MaxAge: Specifies how long the results of a preflight request can be
	// cached. This translates to the content for the Access-Control-Max-Age
	// header.
	MaxAge int64 `json:"maxAge,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AllowCredentials") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AllowCredentials") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CorsPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod CorsPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CustomerEncryptionKey: Represents a customer-supplied encryption key
type CustomerEncryptionKey struct {
	// KmsKeyName: The name of the encryption key that is stored in Google
	// Cloud KMS.
	KmsKeyName string `json:"kmsKeyName,omitempty"`

	// RawKey: Specifies a 256-bit customer-supplied encryption key, encoded
	// in RFC 4648 base64 to either encrypt or decrypt this resource.
	RawKey string `json:"rawKey,omitempty"`

	// Sha256: [Output only] The RFC 4648 base64 encoded SHA-256 hash of the
	// customer-supplied encryption key that protects this resource.
	Sha256 string `json:"sha256,omitempty"`

	// ForceSendFields is a list of field names (e.g. "KmsKeyName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "KmsKeyName") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CustomerEncryptionKey) MarshalJSON() ([]byte, error) {
	type NoMethod CustomerEncryptionKey
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type CustomerEncryptionKeyProtectedDisk struct {
	// DiskEncryptionKey: Decrypts data associated with the disk with a
	// customer-supplied encryption key.
	DiskEncryptionKey *CustomerEncryptionKey `json:"diskEncryptionKey,omitempty"`

	// Source: Specifies a valid partial or full URL to an existing
	// Persistent Disk resource. This field is only applicable for
	// persistent disks.
	Source string `json:"source,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DiskEncryptionKey")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DiskEncryptionKey") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CustomerEncryptionKeyProtectedDisk) MarshalJSON() ([]byte, error) {
	type NoMethod CustomerEncryptionKeyProtectedDisk
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeprecationStatus: Deprecation status for a public resource.
type DeprecationStatus struct {
	// Deleted: An optional RFC3339 timestamp on or after which the state of
	// this resource is intended to change to DELETED. This is only
	// informational and the status will not change unless the client
	// explicitly changes it.
	Deleted string `json:"deleted,omitempty"`

	// Deprecated: An optional RFC3339 timestamp on or after which the state
	// of this resource is intended to change to DEPRECATED. This is only
	// informational and the status will not change unless the client
	// explicitly changes it.
	Deprecated string `json:"deprecated,omitempty"`

	// Obsolete: An optional RFC3339 timestamp on or after which the state
	// of this resource is intended to change to OBSOLETE. This is only
	// informational and the status will not change unless the client
	// explicitly changes it.
	Obsolete string `json:"obsolete,omitempty"`

	// Replacement: The URL of the suggested replacement for a deprecated
	// resource. The suggested replacement resource must be the same kind of
	// resource as the deprecated resource.
	Replacement string `json:"replacement,omitempty"`

	// State: The deprecation state of this resource. This can be ACTIVE,
	// DEPRECATED, OBSOLETE, or DELETED. Operations which communicate the
	// end of life date for an image, can use ACTIVE. Operations which
	// create a new resource using a DEPRECATED resource will return
	// successfully, but with a warning indicating the deprecated resource
	// and recommending its replacement. Operations which use OBSOLETE or
	// DELETED resources will be rejected and result in an error.
	//
	// Possible values:
	//   "ACTIVE"
	//   "DELETED"
	//   "DEPRECATED"
	//   "OBSOLETE"
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Deleted") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Deleted") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeprecationStatus) MarshalJSON() ([]byte, error) {
	type NoMethod DeprecationStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Disk: Represents a Persistent Disk resource.
//
// Persistent disks are required for running your VM instances. Create
// both boot and non-boot (data) persistent disks. For more information,
// read Persistent Disks. For more storage options, read Storage
// options.
//
// The disks resource represents a zonal persistent disk. For more
// information, read Zonal persistent disks.
//
// The regionDisks resource represents a regional persistent disk. For
// more information, read  Regional resources. (== resource_for
// beta.disks ==) (== resource_for v1.disks ==) (== resource_for
// v1.regionDisks ==) (== resource_for beta.regionDisks ==)
type Disk struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// DiskEncryptionKey: Encrypts the disk using a customer-supplied
	// encryption key.
	//
	// After you encrypt a disk with a customer-supplied key, you must
	// provide the same key if you use the disk later (e.g. to create a disk
	// snapshot, to create a disk image, to create a machine image, or to
	// attach the disk to a virtual machine).
	//
	// Customer-supplied encryption keys do not protect access to metadata
	// of the disk.
	//
	// If you do not provide an encryption key when creating the disk, then
	// the disk will be encrypted using an automatically generated key and
	// you do not need to provide a key to use the disk later.
	DiskEncryptionKey *CustomerEncryptionKey `json:"diskEncryptionKey,omitempty"`

	// GuestOsFeatures: A list of features to enable on the guest operating
	// system. Applicable only for bootable images. Read  Enabling guest
	// operating system features to see a list of available options.
	GuestOsFeatures []*GuestOsFeature `json:"guestOsFeatures,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#disk for
	// disks.
	Kind string `json:"kind,omitempty"`

	// LabelFingerprint: A fingerprint for the labels being applied to this
	// disk, which is essentially a hash of the labels set used for
	// optimistic locking. The fingerprint is initially generated by Compute
	// Engine and changes after every request to modify or update labels.
	// You must always provide an up-to-date fingerprint hash in order to
	// update or change labels, otherwise the request will fail with error
	// 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve a
	// disk.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: Labels to apply to this disk. These can be later modified by
	// the setLabels method.
	Labels map[string]string `json:"labels,omitempty"`

	// LastAttachTimestamp: [Output Only] Last attach timestamp in RFC3339
	// text format.
	LastAttachTimestamp string `json:"lastAttachTimestamp,omitempty"`

	// LastDetachTimestamp: [Output Only] Last detach timestamp in RFC3339
	// text format.
	LastDetachTimestamp string `json:"lastDetachTimestamp,omitempty"`

	// LicenseCodes: Integer license codes indicating which licenses are
	// attached to this disk.
	LicenseCodes googleapi.Int64s `json:"licenseCodes,omitempty"`

	// Licenses: A list of publicly visible licenses. Reserved for Google's
	// use.
	Licenses []string `json:"licenses,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Options: Internal use only.
	Options string `json:"options,omitempty"`

	// PhysicalBlockSizeBytes: Physical block size of the persistent disk,
	// in bytes. If not present in a request, a default value is used.
	// Currently supported sizes are 4096 and 16384, other sizes may be
	// added in the future. If an unsupported value is requested, the error
	// message will list the supported values for the caller's project.
	PhysicalBlockSizeBytes int64 `json:"physicalBlockSizeBytes,omitempty,string"`

	// Region: [Output Only] URL of the region where the disk resides. Only
	// applicable for regional resources. You must specify this field as
	// part of the HTTP request URL. It is not settable as a field in the
	// request body.
	Region string `json:"region,omitempty"`

	// ReplicaZones: URLs of the zones where the disk should be replicated
	// to. Only applicable for regional resources.
	ReplicaZones []string `json:"replicaZones,omitempty"`

	// ResourcePolicies: Resource policies applied to this disk for
	// automatic snapshot creations.
	ResourcePolicies []string `json:"resourcePolicies,omitempty"`

	// SelfLink: [Output Only] Server-defined fully-qualified URL for this
	// resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SizeGb: Size of the persistent disk, specified in GB. You can specify
	// this field when creating a persistent disk using the sourceImage or
	// sourceSnapshot parameter, or specify it alone to create an empty
	// persistent disk.
	//
	// If you specify this field along with sourceImage or sourceSnapshot,
	// the value of sizeGb must not be less than the size of the sourceImage
	// or the size of the snapshot. Acceptable values are 1 to 65536,
	// inclusive.
	SizeGb int64 `json:"sizeGb,omitempty,string"`

	// SourceImage: The source image used to create this disk. If the source
	// image is deleted, this field will not be set.
	//
	// To create a disk with one of the public operating system images,
	// specify the image by its family name. For example, specify
	// family/debian-9 to use the latest Debian 9
	// image:
	// projects/debian-cloud/global/images/family/debian-9
	//
	//
	// Alternati
	// vely, use a specific version of a public operating system
	// image:
	// projects/debian-cloud/global/images/debian-9-stretch-vYYYYMMDD
	//
	//
	//
	// To create a disk with a custom image that you created, specify the
	// image name in the following
	// format:
	// global/images/my-custom-image
	//
	//
	// You can also specify a custom image by its image family, which
	// returns the latest version of the image in that family. Replace the
	// image name with
	// family/family-name:
	// global/images/family/my-image-family
	SourceImage string `json:"sourceImage,omitempty"`

	// SourceImageEncryptionKey: The customer-supplied encryption key of the
	// source image. Required if the source image is protected by a
	// customer-supplied encryption key.
	SourceImageEncryptionKey *CustomerEncryptionKey `json:"sourceImageEncryptionKey,omitempty"`

	// SourceImageId: [Output Only] The ID value of the image used to create
	// this disk. This value identifies the exact image that was used to
	// create this persistent disk. For example, if you created the
	// persistent disk from an image that was later deleted and recreated
	// under the same name, the source image ID would identify the exact
	// version of the image that was used.
	SourceImageId string `json:"sourceImageId,omitempty"`

	// SourceSnapshot: The source snapshot used to create this disk. You can
	// provide this as a partial or full URL to the resource. For example,
	// the following are valid values:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/global/snapshots/snapshot
	// - projects/project/global/snapshots/snapshot
	// - global/snapshots/snapshot
	SourceSnapshot string `json:"sourceSnapshot,omitempty"`

	// SourceSnapshotEncryptionKey: The customer-supplied encryption key of
	// the source snapshot. Required if the source snapshot is protected by
	// a customer-supplied encryption key.
	SourceSnapshotEncryptionKey *CustomerEncryptionKey `json:"sourceSnapshotEncryptionKey,omitempty"`

	// SourceSnapshotId: [Output Only] The unique ID of the snapshot used to
	// create this disk. This value identifies the exact snapshot that was
	// used to create this persistent disk. For example, if you created the
	// persistent disk from a snapshot that was later deleted and recreated
	// under the same name, the source snapshot ID would identify the exact
	// version of the snapshot that was used.
	SourceSnapshotId string `json:"sourceSnapshotId,omitempty"`

	// Status: [Output Only] The status of disk creation. CREATING: Disk is
	// provisioning. RESTORING: Source data is being copied into the disk.
	// FAILED: Disk creation failed. READY: Disk is ready for use. DELETING:
	// Disk is deleting.
	//
	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "FAILED"
	//   "READY"
	//   "RESTORING"
	Status string `json:"status,omitempty"`

	// Type: URL of the disk type resource describing which disk type to use
	// to create the disk. Provide this when creating the disk. For example:
	// projects/project/zones/zone/diskTypes/pd-standard or pd-ssd
	Type string `json:"type,omitempty"`

	// Users: [Output Only] Links to the users of the disk (attached
	// instances) in form: projects/project/zones/zone/instances/instance
	Users []string `json:"users,omitempty"`

	// Zone: [Output Only] URL of the zone where the disk resides. You must
	// specify this field as part of the HTTP request URL. It is not
	// settable as a field in the request body.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Disk) MarshalJSON() ([]byte, error) {
	type NoMethod Disk
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of DisksScopedList resources.
	Items map[string]DisksScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#diskAggregatedList for aggregated lists of persistent disks.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *DiskAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod DiskAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskAggregatedListWarning: [Output Only] Informational warning
// message.
type DiskAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*DiskAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod DiskAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod DiskAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskInstantiationConfig: A specification of the desired way to
// instantiate a disk in the instance template when its created from a
// source instance.
type DiskInstantiationConfig struct {
	// AutoDelete: Specifies whether the disk will be auto-deleted when the
	// instance is deleted (but not when the disk is detached from the
	// instance).
	AutoDelete bool `json:"autoDelete,omitempty"`

	// CustomImage: The custom source image to be used to restore this disk
	// when instantiating this instance template.
	CustomImage string `json:"customImage,omitempty"`

	// DeviceName: Specifies the device name of the disk to which the
	// configurations apply to.
	DeviceName string `json:"deviceName,omitempty"`

	// InstantiateFrom: Specifies whether to include the disk and what image
	// to use. Possible values are:
	// - source-image: to use the same image that was used to create the
	// source instance's corresponding disk. Applicable to the boot disk and
	// additional read-write disks.
	// - source-image-family: to use the same image family that was used to
	// create the source instance's corresponding disk. Applicable to the
	// boot disk and additional read-write disks.
	// - custom-image: to use a user-provided image url for disk creation.
	// Applicable to the boot disk and additional read-write disks.
	// - attach-read-only: to attach a read-only disk. Applicable to
	// read-only disks.
	// - do-not-include: to exclude a disk from the template. Applicable to
	// additional read-write disks, local SSDs, and read-only disks.
	//
	// Possible values:
	//   "ATTACH_READ_ONLY"
	//   "BLANK"
	//   "CUSTOM_IMAGE"
	//   "DEFAULT"
	//   "DO_NOT_INCLUDE"
	//   "SOURCE_IMAGE"
	//   "SOURCE_IMAGE_FAMILY"
	InstantiateFrom string `json:"instantiateFrom,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoDelete") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoDelete") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskInstantiationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod DiskInstantiationConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskList: A list of Disk resources.
type DiskList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Disk resources.
	Items []*Disk `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#diskList for
	// lists of disks.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *DiskListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskList) MarshalJSON() ([]byte, error) {
	type NoMethod DiskList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskListWarning: [Output Only] Informational warning message.
type DiskListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*DiskListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod DiskListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod DiskListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskMoveRequest struct {
	// DestinationZone: The URL of the destination zone to move the disk.
	// This can be a full or partial URL. For example, the following are all
	// valid URLs to a zone:
	// - https://www.googleapis.com/compute/v1/projects/project/zones/zone
	//
	// - projects/project/zones/zone
	// - zones/zone
	DestinationZone string `json:"destinationZone,omitempty"`

	// TargetDisk: The URL of the target disk to move. This can be a full or
	// partial URL. For example, the following are all valid URLs to a disk:
	//
	// -
	// https://www.googleapis.com/compute/v1/projects/project/zones/zone/disks/disk
	// - projects/project/zones/zone/disks/disk
	// - zones/zone/disks/disk
	TargetDisk string `json:"targetDisk,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DestinationZone") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DestinationZone") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *DiskMoveRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DiskMoveRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskType: Represents a Disk Type resource.
//
// You can choose from a variety of disk types based on your needs. For
// more information, read Storage options.
//
// The diskTypes resource represents disk types for a zonal persistent
// disk. For more information, read Zonal persistent disks.
//
// The regionDiskTypes resource represents disk types for a regional
// persistent disk. For more information, read Regional persistent
// disks. (== resource_for beta.diskTypes ==) (== resource_for
// v1.diskTypes ==) (== resource_for v1.regionDiskTypes ==) (==
// resource_for beta.regionDiskTypes ==)
type DiskType struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// DefaultDiskSizeGb: [Output Only] Server-defined default disk size in
	// GB.
	DefaultDiskSizeGb int64 `json:"defaultDiskSizeGb,omitempty,string"`

	// Deprecated: [Output Only] The deprecation status associated with this
	// disk type.
	Deprecated *DeprecationStatus `json:"deprecated,omitempty"`

	// Description: [Output Only] An optional description of this resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#diskType for
	// disk types.
	Kind string `json:"kind,omitempty"`

	// Name: [Output Only] Name of the resource.
	Name string `json:"name,omitempty"`

	// Region: [Output Only] URL of the region where the disk type resides.
	// Only applicable for regional resources. You must specify this field
	// as part of the HTTP request URL. It is not settable as a field in the
	// request body.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ValidDiskSize: [Output Only] An optional textual description of the
	// valid disk size, such as "10GB-10TB".
	ValidDiskSize string `json:"validDiskSize,omitempty"`

	// Zone: [Output Only] URL of the zone where the disk type resides. You
	// must specify this field as part of the HTTP request URL. It is not
	// settable as a field in the request body.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *DiskType) MarshalJSON() ([]byte, error) {
	type NoMethod DiskType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskTypeAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of DiskTypesScopedList resources.
	Items map[string]DiskTypesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#diskTypeAggregatedList.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *DiskTypeAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypeAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypeAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskTypeAggregatedListWarning: [Output Only] Informational warning
// message.
type DiskTypeAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*DiskTypeAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypeAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypeAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskTypeAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypeAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypeAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskTypeList: Contains a list of disk types.
type DiskTypeList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of DiskType resources.
	Items []*DiskType `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#diskTypeList for
	// disk types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *DiskTypeListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypeList) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypeList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskTypeListWarning: [Output Only] Informational warning message.
type DiskTypeListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*DiskTypeListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypeListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypeListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskTypeListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypeListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypeListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskTypesScopedList struct {
	// DiskTypes: [Output Only] A list of disk types contained in this
	// scope.
	DiskTypes []*DiskType `json:"diskTypes,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of disk types when the list is empty.
	Warning *DiskTypesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DiskTypes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DiskTypes") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DiskTypesScopedListWarning: [Output Only] Informational warning which
// replaces the list of disk types when the list is empty.
type DiskTypesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*DiskTypesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DiskTypesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DiskTypesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod DiskTypesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DisksAddResourcePoliciesRequest struct {
	// ResourcePolicies: Resource policies to be added to this disk.
	// Currently you can only specify one policy here.
	ResourcePolicies []string `json:"resourcePolicies,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourcePolicies") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ResourcePolicies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *DisksAddResourcePoliciesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DisksAddResourcePoliciesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DisksRemoveResourcePoliciesRequest struct {
	// ResourcePolicies: Resource policies to be removed from this disk.
	ResourcePolicies []string `json:"resourcePolicies,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourcePolicies") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ResourcePolicies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *DisksRemoveResourcePoliciesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DisksRemoveResourcePoliciesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DisksResizeRequest struct {
	// SizeGb: The new size of the persistent disk, which is specified in
	// GB.
	SizeGb int64 `json:"sizeGb,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "SizeGb") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SizeGb") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DisksResizeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DisksResizeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DisksScopedList struct {
	// Disks: [Output Only] A list of disks contained in this scope.
	Disks []*Disk `json:"disks,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of disks when the list is empty.
	Warning *DisksScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Disks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Disks") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DisksScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod DisksScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DisksScopedListWarning: [Output Only] Informational warning which
// replaces the list of disks when the list is empty.
type DisksScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*DisksScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DisksScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod DisksScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DisksScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DisksScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod DisksScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DisplayDevice: A set of Display Device options
type DisplayDevice struct {
	// EnableDisplay: Defines whether the instance has Display enabled.
	EnableDisplay bool `json:"enableDisplay,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EnableDisplay") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EnableDisplay") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DisplayDevice) MarshalJSON() ([]byte, error) {
	type NoMethod DisplayDevice
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DistributionPolicy struct {
	// Zones: Zones where the regional managed instance group will create
	// and manage instances.
	Zones []*DistributionPolicyZoneConfiguration `json:"zones,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Zones") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Zones") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DistributionPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod DistributionPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DistributionPolicyZoneConfiguration struct {
	// Zone: The URL of the zone. The zone must exist in the region where
	// the managed instance group is located.
	Zone string `json:"zone,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Zone") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Zone") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DistributionPolicyZoneConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod DistributionPolicyZoneConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Duration: A Duration represents a fixed-length span of time
// represented as a count of seconds and fractions of seconds at
// nanosecond resolution. It is independent of any calendar and concepts
// like "day" or "month". Range is approximately 10,000 years.
type Duration struct {
	// Nanos: Span of time that's a fraction of a second at nanosecond
	// resolution. Durations less than one second are represented with a 0
	// `seconds` field and a positive `nanos` field. Must be from 0 to
	// 999,999,999 inclusive.
	Nanos int64 `json:"nanos,omitempty"`

	// Seconds: Span of time at a resolution of a second. Must be from 0 to
	// 315,576,000,000 inclusive. Note: these bounds are computed from: 60
	// sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
	Seconds int64 `json:"seconds,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Nanos") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Nanos") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Duration) MarshalJSON() ([]byte, error) {
	type NoMethod Duration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Expr: Represents an expression text. Example:
//
// title: "User account presence" description: "Determines whether the
// request has a user account" expression: "size(request.user) > 0"
type Expr struct {
	// Description: An optional description of the expression. This is a
	// longer text which describes the expression, e.g. when hovered over it
	// in a UI.
	Description string `json:"description,omitempty"`

	// Expression: Textual representation of an expression in Common
	// Expression Language syntax.
	//
	// The application context of the containing message determines which
	// well-known feature set of CEL is supported.
	Expression string `json:"expression,omitempty"`

	// Location: An optional string indicating the location of the
	// expression for error reporting, e.g. a file name and a position in
	// the file.
	Location string `json:"location,omitempty"`

	// Title: An optional title for the expression, i.e. a short string
	// describing its purpose. This can be used e.g. in UIs which allow to
	// enter the expression.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Expr) MarshalJSON() ([]byte, error) {
	type NoMethod Expr
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExternalVpnGateway: External VPN gateway is the on-premises VPN
// gateway(s) or another cloud provider?s VPN gateway that connects to
// your Google Cloud VPN gateway. To create a highly available VPN from
// Google Cloud to your on-premises side or another Cloud provider's VPN
// gateway, you must create a external VPN gateway resource in GCP,
// which provides the information to GCP about your external VPN
// gateway.
type ExternalVpnGateway struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Interfaces: List of interfaces for this external VPN gateway.
	Interfaces []*ExternalVpnGatewayInterface `json:"interfaces,omitempty"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#externalVpnGateway for externalVpnGateways.
	Kind string `json:"kind,omitempty"`

	// LabelFingerprint: A fingerprint for the labels being applied to this
	// ExternalVpnGateway, which is essentially a hash of the labels set
	// used for optimistic locking. The fingerprint is initially generated
	// by Compute Engine and changes after every request to modify or update
	// labels. You must always provide an up-to-date fingerprint hash in
	// order to update or change labels, otherwise the request will fail
	// with error 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve an
	// ExternalVpnGateway.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: Labels to apply to this ExternalVpnGateway resource. These
	// can be later modified by the setLabels method. Each label key/value
	// must comply with RFC1035. Label values may be empty.
	Labels map[string]string `json:"labels,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// RedundancyType: Indicates the user-supplied redundancy type of this
	// external VPN gateway.
	//
	// Possible values:
	//   "FOUR_IPS_REDUNDANCY"
	//   "SINGLE_IP_INTERNALLY_REDUNDANT"
	//   "TWO_IPS_REDUNDANCY"
	RedundancyType string `json:"redundancyType,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ExternalVpnGateway) MarshalJSON() ([]byte, error) {
	type NoMethod ExternalVpnGateway
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExternalVpnGatewayInterface: The interface for the external VPN
// gateway.
type ExternalVpnGatewayInterface struct {
	// Id: The numeric ID of this interface. The allowed input values for
	// this id for different redundancy types of external VPN gateway:
	// SINGLE_IP_INTERNALLY_REDUNDANT - 0 TWO_IPS_REDUNDANCY - 0, 1
	// FOUR_IPS_REDUNDANCY - 0, 1, 2, 3
	Id int64 `json:"id,omitempty"`

	// IpAddress: IP address of the interface in the external VPN gateway.
	// Only IPv4 is supported. This IP address can be either from your
	// on-premise gateway or another Cloud provider?s VPN gateway, it cannot
	// be an IP address from Google Compute Engine.
	IpAddress string `json:"ipAddress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ExternalVpnGatewayInterface) MarshalJSON() ([]byte, error) {
	type NoMethod ExternalVpnGatewayInterface
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExternalVpnGatewayList: Response to the list request, and contains a
// list of externalVpnGateways.
type ExternalVpnGatewayList struct {
	Etag string `json:"etag,omitempty"`

	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of ExternalVpnGateway resources.
	Items []*ExternalVpnGateway `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#externalVpnGatewayList  for lists of externalVpnGateways.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ExternalVpnGatewayListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Etag") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ExternalVpnGatewayList) MarshalJSON() ([]byte, error) {
	type NoMethod ExternalVpnGatewayList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExternalVpnGatewayListWarning: [Output Only] Informational warning
// message.
type ExternalVpnGatewayListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ExternalVpnGatewayListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ExternalVpnGatewayListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ExternalVpnGatewayListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ExternalVpnGatewayListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ExternalVpnGatewayListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ExternalVpnGatewayListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Firewall: Represents a Firewall Rule resource.
//
// Firewall rules allow or deny ingress traffic to, and egress traffic
// from your instances. For more information, read Firewall rules.
type Firewall struct {
	// Allowed: The list of ALLOW rules specified by this firewall. Each
	// rule specifies a protocol and port-range tuple that describes a
	// permitted connection.
	Allowed []*FirewallAllowed `json:"allowed,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Denied: The list of DENY rules specified by this firewall. Each rule
	// specifies a protocol and port-range tuple that describes a denied
	// connection.
	Denied []*FirewallDenied `json:"denied,omitempty"`

	// Description: An optional description of this resource. Provide this
	// field when you create the resource.
	Description string `json:"description,omitempty"`

	// DestinationRanges: If destination ranges are specified, the firewall
	// rule applies only to traffic that has destination IP address in these
	// ranges. These ranges must be expressed in CIDR format. Only IPv4 is
	// supported.
	DestinationRanges []string `json:"destinationRanges,omitempty"`

	// Direction: Direction of traffic to which this firewall applies,
	// either `INGRESS` or `EGRESS`. The default is `INGRESS`. For `INGRESS`
	// traffic, you cannot specify the destinationRanges field, and for
	// `EGRESS` traffic, you cannot specify the sourceRanges or sourceTags
	// fields.
	//
	// Possible values:
	//   "EGRESS"
	//   "INGRESS"
	Direction string `json:"direction,omitempty"`

	// Disabled: Denotes whether the firewall rule is disabled. When set to
	// true, the firewall rule is not enforced and the network behaves as if
	// it did not exist. If this is unspecified, the firewall rule will be
	// enabled.
	Disabled bool `json:"disabled,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#firewall for
	// firewall rules.
	Kind string `json:"kind,omitempty"`

	// LogConfig: This field denotes the logging options for a particular
	// firewall rule. If logging is enabled, logs will be exported to
	// Stackdriver.
	LogConfig *FirewallLogConfig `json:"logConfig,omitempty"`

	// Name: Name of the resource; provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?. The first
	// character must be a lowercase letter, and all following characters
	// (except for the last character) must be a dash, lowercase letter, or
	// digit. The last character must be a lowercase letter or digit.
	Name string `json:"name,omitempty"`

	// Network: URL of the network resource for this firewall rule. If not
	// specified when creating a firewall rule, the default network is
	// used:
	// global/networks/default
	// If you choose to specify this field, you can specify the network as a
	// full or partial URL. For example, the following are all valid URLs:
	//
	// -
	// https://www.googleapis.com/compute/v1/projects/myproject/global/networks/my-network
	// - projects/myproject/global/networks/my-network
	// - global/networks/default
	Network string `json:"network,omitempty"`

	// Priority: Priority for this rule. This is an integer between `0` and
	// `65535`, both inclusive. The default value is `1000`. Relative
	// priorities determine which rule takes effect if multiple rules apply.
	// Lower values indicate higher priority. For example, a rule with
	// priority `0` has higher precedence than a rule with priority `1`.
	// DENY rules take precedence over ALLOW rules if they have equal
	// priority. Note that VPC networks have implied rules with a priority
	// of `65535`. To avoid conflicts with the implied rules, use a priority
	// number less than `65535`.
	Priority int64 `json:"priority,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SourceRanges: If source ranges are specified, the firewall rule
	// applies only to traffic that has a source IP address in these ranges.
	// These ranges must be expressed in CIDR format. One or both of
	// sourceRanges and sourceTags may be set. If both fields are set, the
	// rule applies to traffic that has a source IP address within
	// sourceRanges OR a source IP from a resource with a matching tag
	// listed in the sourceTags field. The connection does not need to match
	// both fields for the rule to apply. Only IPv4 is supported.
	SourceRanges []string `json:"sourceRanges,omitempty"`

	// SourceServiceAccounts: If source service accounts are specified, the
	// firewall rules apply only to traffic originating from an instance
	// with a service account in this list. Source service accounts cannot
	// be used to control traffic to an instance's external IP address
	// because service accounts are associated with an instance, not an IP
	// address. sourceRanges can be set at the same time as
	// sourceServiceAccounts. If both are set, the firewall applies to
	// traffic that has a source IP address within the sourceRanges OR a
	// source IP that belongs to an instance with service account listed in
	// sourceServiceAccount. The connection does not need to match both
	// fields for the firewall to apply. sourceServiceAccounts cannot be
	// used at the same time as sourceTags or targetTags.
	SourceServiceAccounts []string `json:"sourceServiceAccounts,omitempty"`

	// SourceTags: If source tags are specified, the firewall rule applies
	// only to traffic with source IPs that match the primary network
	// interfaces of VM instances that have the tag and are in the same VPC
	// network. Source tags cannot be used to control traffic to an
	// instance's external IP address, it only applies to traffic between
	// instances in the same virtual network. Because tags are associated
	// with instances, not IP addresses. One or both of sourceRanges and
	// sourceTags may be set. If both fields are set, the firewall applies
	// to traffic that has a source IP address within sourceRanges OR a
	// source IP from a resource with a matching tag listed in the
	// sourceTags field. The connection does not need to match both fields
	// for the firewall to apply.
	SourceTags []string `json:"sourceTags,omitempty"`

	// TargetServiceAccounts: A list of service accounts indicating sets of
	// instances located in the network that may make network connections as
	// specified in allowed[]. targetServiceAccounts cannot be used at the
	// same time as targetTags or sourceTags. If neither
	// targetServiceAccounts nor targetTags are specified, the firewall rule
	// applies to all instances on the specified network.
	TargetServiceAccounts []string `json:"targetServiceAccounts,omitempty"`

	// TargetTags: A list of tags that controls which instances the firewall
	// rule applies to. If targetTags are specified, then the firewall rule
	// applies only to instances in the VPC network that have one of those
	// tags. If no targetTags are specified, the firewall rule applies to
	// all instances on the specified network.
	TargetTags []string `json:"targetTags,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Allowed") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Allowed") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Firewall) MarshalJSON() ([]byte, error) {
	type NoMethod Firewall
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type FirewallAllowed struct {
	// IPProtocol: The IP protocol to which this rule applies. The protocol
	// type is required when creating a firewall rule. This value can either
	// be one of the following well known protocol strings (tcp, udp, icmp,
	// esp, ah, ipip, sctp) or the IP protocol number.
	IPProtocol string `json:"IPProtocol,omitempty"`

	// Ports: An optional list of ports to which this rule applies. This
	// field is only applicable for the UDP or TCP protocol. Each entry must
	// be either an integer or a range. If not specified, this rule applies
	// to connections through any port.
	//
	// Example inputs include: ["22"], ["80","443"], and ["12345-12349"].
	Ports []string `json:"ports,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IPProtocol") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IPProtocol") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FirewallAllowed) MarshalJSON() ([]byte, error) {
	type NoMethod FirewallAllowed
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type FirewallDenied struct {
	// IPProtocol: The IP protocol to which this rule applies. The protocol
	// type is required when creating a firewall rule. This value can either
	// be one of the following well known protocol strings (tcp, udp, icmp,
	// esp, ah, ipip, sctp) or the IP protocol number.
	IPProtocol string `json:"IPProtocol,omitempty"`

	// Ports: An optional list of ports to which this rule applies. This
	// field is only applicable for the UDP or TCP protocol. Each entry must
	// be either an integer or a range. If not specified, this rule applies
	// to connections through any port.
	//
	// Example inputs include: ["22"], ["80","443"], and ["12345-12349"].
	Ports []string `json:"ports,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IPProtocol") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IPProtocol") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FirewallDenied) MarshalJSON() ([]byte, error) {
	type NoMethod FirewallDenied
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FirewallList: Contains a list of firewalls.
type FirewallList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Firewall resources.
	Items []*Firewall `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#firewallList for
	// lists of firewalls.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *FirewallListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FirewallList) MarshalJSON() ([]byte, error) {
	type NoMethod FirewallList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FirewallListWarning: [Output Only] Informational warning message.
type FirewallListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*FirewallListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FirewallListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod FirewallListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type FirewallListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FirewallListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod FirewallListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FirewallLogConfig: The available logging options for a firewall rule.
type FirewallLogConfig struct {
	// Enable: This field denotes whether to enable logging for a particular
	// firewall rule.
	Enable bool `json:"enable,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Enable") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Enable") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FirewallLogConfig) MarshalJSON() ([]byte, error) {
	type NoMethod FirewallLogConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FixedOrPercent: Encapsulates numeric value that can be either
// absolute or relative.
type FixedOrPercent struct {
	// Calculated: [Output Only] Absolute value of VM instances calculated
	// based on the specific mode.
	//
	//
	// - If the value is fixed, then the calculated value is equal to the
	// fixed value.
	// - If the value is a percent, then the calculated value is percent/100
	// * targetSize. For example, the calculated value of a 80% of a managed
	// instance group with 150 instances would be (80/100 * 150) = 120 VM
	// instances. If there is a remainder, the number is rounded up.
	Calculated int64 `json:"calculated,omitempty"`

	// Fixed: Specifies a fixed number of VM instances. This must be a
	// positive integer.
	Fixed int64 `json:"fixed,omitempty"`

	// Percent: Specifies a percentage of instances between 0 to 100%,
	// inclusive. For example, specify 80 for 80%.
	Percent int64 `json:"percent,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Calculated") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Calculated") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FixedOrPercent) MarshalJSON() ([]byte, error) {
	type NoMethod FixedOrPercent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ForwardingRule: Represents a Forwarding Rule resource.
//
// A forwarding rule and its corresponding IP address represent the
// frontend configuration of a Google Cloud Platform load balancer.
// Forwarding rules can also reference target instances and Cloud VPN
// Classic gateways (targetVpnGateway).
//
// For more information, read Forwarding rule concepts and Using
// protocol forwarding.
//
// (== resource_for beta.forwardingRules ==) (== resource_for
// v1.forwardingRules ==) (== resource_for beta.globalForwardingRules
// ==) (== resource_for v1.globalForwardingRules ==) (== resource_for
// beta.regionForwardingRules ==) (== resource_for
// v1.regionForwardingRules ==)
type ForwardingRule struct {
	// IPAddress: IP address that this forwarding rule serves. When a client
	// sends traffic to this IP address, the forwarding rule directs the
	// traffic to the target that you specify in the forwarding rule.
	//
	// If you don't specify a reserved IP address, an ephemeral IP address
	// is assigned. Methods for specifying an IP address:
	//
	// * IPv4 dotted decimal, as in `100.1.2.3` * Full URL, as in
	// https://www.googleapis.com/compute/v1/projects/project_id/regions/region/addresses/address-name * Partial URL or by name, as in: * projects/project_id/regions/region/addresses/address-name * regions/region/addresses/address-name * global/addresses/address-name * address-name
	//
	// The loadBalancingScheme and the forwarding rule's target determine
	// the type of IP address that you can use. For detailed information,
	// refer to [IP address
	// specifications](/load-balancing/docs/forwarding-rule-concepts#ip_addre
	// ss_specifications).
	IPAddress string `json:"IPAddress,omitempty"`

	// IPProtocol: The IP protocol to which this rule applies. Valid options
	// are TCP, UDP, ESP, AH, SCTP or ICMP.
	//
	// For Internal TCP/UDP Load Balancing, the load balancing scheme is
	// INTERNAL, and one of TCP or UDP are valid. For Traffic Director, the
	// load balancing scheme is INTERNAL_SELF_MANAGED, and only TCPis valid.
	// For Internal HTTP(S) Load Balancing, the load balancing scheme is
	// INTERNAL_MANAGED, and only TCP is valid. For HTTP(S), SSL Proxy, and
	// TCP Proxy Load Balancing, the load balancing scheme is EXTERNAL and
	// only TCP is valid. For Network TCP/UDP Load Balancing, the load
	// balancing scheme is EXTERNAL, and one of TCP or UDP is valid.
	//
	// Possible values:
	//   "AH"
	//   "ESP"
	//   "ICMP"
	//   "SCTP"
	//   "TCP"
	//   "UDP"
	IPProtocol string `json:"IPProtocol,omitempty"`

	// AllPorts: This field is used along with the backend_service field for
	// internal load balancing or with the target field for internal
	// TargetInstance. This field cannot be used with port or portRange
	// fields.
	//
	// When the load balancing scheme is INTERNAL and protocol is TCP/UDP,
	// specify this field to allow packets addressed to any ports will be
	// forwarded to the backends configured with this forwarding rule.
	AllPorts bool `json:"allPorts,omitempty"`

	// BackendService: This field is only used for INTERNAL load
	// balancing.
	//
	// For internal load balancing, this field identifies the BackendService
	// resource to receive the matched traffic.
	BackendService string `json:"backendService,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// IpVersion: The IP Version that will be used by this forwarding rule.
	// Valid options are IPV4 or IPV6. This can only be specified for an
	// external global forwarding rule.
	//
	// Possible values:
	//   "IPV4"
	//   "IPV6"
	//   "UNSPECIFIED_VERSION"
	IpVersion string `json:"ipVersion,omitempty"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#forwardingRule for Forwarding Rule resources.
	Kind string `json:"kind,omitempty"`

	// LoadBalancingScheme: Specifies the forwarding rule type. EXTERNAL is
	// used for: - Classic Cloud VPN gateways - Protocol forwarding to VMs
	// from an external IP address - The following load balancers: HTTP(S),
	// SSL Proxy, TCP Proxy, and Network TCP/UDP.
	//
	// INTERNAL is used for: - Protocol forwarding to VMs from an internal
	// IP address - Internal TCP/UDP load balancers
	//
	// INTERNAL_MANAGED is used for: - Internal HTTP(S) load
	// balancers
	//
	// INTERNAL_SELF_MANAGED is used for: - Traffic Director
	//
	// For more information about forwarding rules, refer to Forwarding rule
	// concepts.
	//
	// Possible values:
	//   "EXTERNAL"
	//   "INTERNAL"
	//   "INTERNAL_MANAGED"
	//   "INTERNAL_SELF_MANAGED"
	//   "INVALID"
	LoadBalancingScheme string `json:"loadBalancingScheme,omitempty"`

	// MetadataFilters: Opaque filter criteria used by Loadbalancer to
	// restrict routing configuration to a limited set xDS compliant
	// clients. In their xDS requests to Loadbalancer, xDS clients present
	// node metadata. If a match takes place, the relevant routing
	// configuration is made available to those proxies.
	// For each metadataFilter in this list, if its filterMatchCriteria is
	// set to MATCH_ANY, at least one of the filterLabels must match the
	// corresponding label provided in the metadata. If its
	// filterMatchCriteria is set to MATCH_ALL, then all of its filterLabels
	// must match with corresponding labels in the provided
	// metadata.
	// metadataFilters specified here can be overridden by those specified
	// in the UrlMap that this ForwardingRule references.
	// metadataFilters only applies to Loadbalancers that have their
	// loadBalancingScheme set to INTERNAL_SELF_MANAGED.
	MetadataFilters []*MetadataFilter `json:"metadataFilters,omitempty"`

	// Name: Name of the resource; provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Network: This field is not used for external load balancing.
	//
	// For INTERNAL and INTERNAL_SELF_MANAGED load balancing, this field
	// identifies the network that the load balanced IP should belong to for
	// this Forwarding Rule. If this field is not specified, the default
	// network will be used.
	Network string `json:"network,omitempty"`

	// NetworkTier: This signifies the networking tier used for configuring
	// this load balancer and can only take the following values: PREMIUM ,
	// STANDARD.
	//
	// For regional ForwardingRule, the valid values are PREMIUM and
	// STANDARD. For GlobalForwardingRule, the valid value is PREMIUM.
	//
	// If this field is not specified, it is assumed to be PREMIUM. If
	// IPAddress is specified, this value must be equal to the networkTier
	// of the Address.
	//
	// Possible values:
	//   "PREMIUM"
	//   "STANDARD"
	NetworkTier string `json:"networkTier,omitempty"`

	// PortRange: This field is deprecated. See the port
	// field.
	PortRange string `json:"portRange,omitempty"`

	// Ports: List of comma-separated ports. The forwarding rule forwards
	// packets with matching destination ports. If the forwarding rule's
	// loadBalancingScheme is EXTERNAL, and the forwarding rule references a
	// target pool, specifying ports is optional. You can specify an
	// unlimited number of ports, but they must be contiguous. If you omit
	// ports, GCP forwards traffic on any port of the forwarding rule's
	// protocol.
	//
	// If the forwarding rule's loadBalancingScheme is EXTERNAL, and the
	// forwarding rule references a target HTTP proxy, target HTTPS proxy,
	// target TCP proxy, target SSL proxy, or target VPN gateway, you must
	// specify ports using the following constraints:
	//
	//
	// - TargetHttpProxy: 80, 8080
	// - TargetHttpsProxy: 443
	// - TargetTcpProxy: 25, 43, 110, 143, 195, 443, 465, 587, 700, 993,
	// 995, 1688, 1883, 5222
	// - TargetSslProxy: 25, 43, 110, 143, 195, 443, 465, 587, 700, 993,
	// 995, 1688, 1883, 5222
	// - TargetVpnGateway: 500, 4500
	//
	// If the forwarding rule's loadBalancingScheme is INTERNAL, you must
	// specify ports in one of the following ways:
	//
	// * A list of up to five ports, which can be non-contiguous * Keyword
	// ALL, which causes the forwarding rule to forward traffic on any port
	// of the forwarding rule's protocol.
	//
	// The ports field is used along with the target field for
	// TargetHttpProxy, TargetHttpsProxy, TargetSslProxy, TargetTcpProxy,
	// TargetVpnGateway, TargetPool, TargetInstance.
	//
	// Applicable only when IPProtocol is TCP, UDP, or SCTP. Forwarding
	// rules with the same [IPAddress, IPProtocol] pair must have disjoint
	// port ranges.
	Ports []string `json:"ports,omitempty"`

	// Region: [Output Only] URL of the region where the regional forwarding
	// rule resides. This field is not applicable to global forwarding
	// rules. You must specify this field as part of the HTTP request URL.
	// It is not settable as a field in the request body.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServiceLabel: An optional prefix to the service name for this
	// Forwarding Rule. If specified, the prefix is the first label of the
	// fully qualified service name.
	//
	// The label must be 1-63 characters long, and comply with RFC1035.
	// Specifically, the label must be 1-63 characters long and match the
	// regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first
	// character must be a lowercase letter, and all following characters
	// must be a dash, lowercase letter, or digit, except the last
	// character, which cannot be a dash.
	//
	// This field is only used for internal load balancing.
	ServiceLabel string `json:"serviceLabel,omitempty"`

	// ServiceName: [Output Only] The internal fully qualified service name
	// for this Forwarding Rule.
	//
	// This field is only used for internal load balancing.
	ServiceName string `json:"serviceName,omitempty"`

	// Subnetwork: This field is only used for INTERNAL load balancing.
	//
	// For internal load balancing, this field identifies the subnetwork
	// that the load balanced IP should belong to for this Forwarding
	// Rule.
	//
	// If the network specified is in auto subnet mode, this field is
	// optional. However, if the network is in custom subnet mode, a
	// subnetwork must be specified.
	Subnetwork string `json:"subnetwork,omitempty"`

	// Target: The URL of the target resource to receive the matched
	// traffic. For regional forwarding rules, this target must live in the
	// same region as the forwarding rule. For global forwarding rules, this
	// target must be a global load balancing resource. The forwarded
	// traffic must be of a type appropriate to the target object. For
	// INTERNAL_SELF_MANAGED load balancing, only HTTP and HTTPS targets are
	// valid.
	Target string `json:"target,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "IPAddress") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IPAddress") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRule) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ForwardingRuleAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of ForwardingRulesScopedList resources.
	Items map[string]ForwardingRulesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#forwardingRuleAggregatedList for lists of forwarding rules.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ForwardingRuleAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRuleAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRuleAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ForwardingRuleAggregatedListWarning: [Output Only] Informational
// warning message.
type ForwardingRuleAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ForwardingRuleAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRuleAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRuleAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ForwardingRuleAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRuleAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRuleAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ForwardingRuleList: Contains a list of ForwardingRule resources.
type ForwardingRuleList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of ForwardingRule resources.
	Items []*ForwardingRule `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ForwardingRuleListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRuleList) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRuleList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ForwardingRuleListWarning: [Output Only] Informational warning
// message.
type ForwardingRuleListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ForwardingRuleListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRuleListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRuleListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ForwardingRuleListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRuleListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRuleListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ForwardingRuleReference struct {
	ForwardingRule string `json:"forwardingRule,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ForwardingRule") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ForwardingRule") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRuleReference) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRuleReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ForwardingRulesScopedList struct {
	// ForwardingRules: A list of forwarding rules contained in this scope.
	ForwardingRules []*ForwardingRule `json:"forwardingRules,omitempty"`

	// Warning: Informational warning which replaces the list of forwarding
	// rules when the list is empty.
	Warning *ForwardingRulesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ForwardingRules") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ForwardingRules") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRulesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRulesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ForwardingRulesScopedListWarning: Informational warning which
// replaces the list of forwarding rules when the list is empty.
type ForwardingRulesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ForwardingRulesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRulesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRulesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ForwardingRulesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ForwardingRulesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardingRulesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GlobalSetLabelsRequest struct {
	// LabelFingerprint: The fingerprint of the previous set of labels for
	// this resource, used to detect conflicts. The fingerprint is initially
	// generated by Compute Engine and changes after every request to modify
	// or update labels. You must always provide an up-to-date fingerprint
	// hash when updating or changing labels, otherwise the request will
	// fail with error 412 conditionNotMet. Make a get() request to the
	// resource to get the latest fingerprint.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: A list of labels to apply for this resource. Each label key &
	// value must comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash. For example, "webserver-frontend": "images". A label value
	// can also be empty (e.g. "my-label": "").
	Labels map[string]string `json:"labels,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LabelFingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LabelFingerprint") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GlobalSetLabelsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GlobalSetLabelsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GlobalSetPolicyRequest struct {
	// Bindings: Flatten Policy to create a backward compatible wire-format.
	// Deprecated. Use 'policy' to specify bindings.
	Bindings []*Binding `json:"bindings,omitempty"`

	// Etag: Flatten Policy to create a backward compatible wire-format.
	// Deprecated. Use 'policy' to specify the etag.
	Etag string `json:"etag,omitempty"`

	// Policy: REQUIRED: The complete policy to be applied to the
	// 'resource'. The size of the policy is limited to a few 10s of KB. An
	// empty policy is in general a valid policy but certain services (like
	// Projects) might reject them.
	Policy *Policy `json:"policy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bindings") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bindings") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GlobalSetPolicyRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GlobalSetPolicyRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GuestAttributes: A guest attributes entry.
type GuestAttributes struct {
	// Kind: [Output Only] Type of the resource. Always
	// compute#guestAttributes for guest attributes entry.
	Kind string `json:"kind,omitempty"`

	// QueryPath: The path to be queried. This can be the default namespace
	// ('/') or a nested namespace ('//') or a specified key ('//')
	QueryPath string `json:"queryPath,omitempty"`

	// QueryValue: [Output Only] The value of the requested queried path.
	QueryValue *GuestAttributesValue `json:"queryValue,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// VariableKey: The key to search for.
	VariableKey string `json:"variableKey,omitempty"`

	// VariableValue: [Output Only] The value found for the requested key.
	VariableValue string `json:"variableValue,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GuestAttributes) MarshalJSON() ([]byte, error) {
	type NoMethod GuestAttributes
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GuestAttributesEntry: A guest attributes namespace/key/value entry.
type GuestAttributesEntry struct {
	// Key: Key for the guest attribute entry.
	Key string `json:"key,omitempty"`

	// Namespace: Namespace for the guest attribute entry.
	Namespace string `json:"namespace,omitempty"`

	// Value: Value for the guest attribute entry.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GuestAttributesEntry) MarshalJSON() ([]byte, error) {
	type NoMethod GuestAttributesEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GuestAttributesValue: Array of guest attribute namespace/key/value
// tuples.
type GuestAttributesValue struct {
	Items []*GuestAttributesEntry `json:"items,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Items") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Items") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GuestAttributesValue) MarshalJSON() ([]byte, error) {
	type NoMethod GuestAttributesValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GuestOsFeature: Guest OS features.
type GuestOsFeature struct {
	// Type: The ID of a supported feature. Read  Enabling guest operating
	// system features to see a list of available options.
	//
	// Possible values:
	//   "FEATURE_TYPE_UNSPECIFIED"
	//   "MULTI_IP_SUBNET"
	//   "SECURE_BOOT"
	//   "UEFI_COMPATIBLE"
	//   "VIRTIO_SCSI_MULTIQUEUE"
	//   "WINDOWS"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Type") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Type") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GuestOsFeature) MarshalJSON() ([]byte, error) {
	type NoMethod GuestOsFeature
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HTTP2HealthCheck struct {
	// Host: The value of the host header in the HTTP/2 health check
	// request. If left empty (default value), the IP on behalf of which
	// this health check is performed will be used.
	Host string `json:"host,omitempty"`

	// Port: The TCP port number for the health check request. The default
	// value is 443. Valid values are 1 through 65535.
	Port int64 `json:"port,omitempty"`

	// PortName: Port name as defined in InstanceGroup#NamedPort#name. If
	// both port and port_name are defined, port takes precedence.
	PortName string `json:"portName,omitempty"`

	// PortSpecification: Specifies how port is selected for health
	// checking, can be one of following values:
	// USE_FIXED_PORT: The port number in
	// port
	// is used for health checking.
	// USE_NAMED_PORT: The
	// portName
	// is used for health checking.
	// USE_SERVING_PORT: For NetworkEndpointGroup, the port specified for
	// each network endpoint is used for health checking. For other
	// backends, the port or named port specified in the Backend Service is
	// used for health checking.
	//
	//
	// If not specified, HTTP2 health check follows behavior specified
	// in
	// port
	// and
	// portName
	// fields.
	//
	// Possible values:
	//   "USE_FIXED_PORT"
	//   "USE_NAMED_PORT"
	//   "USE_SERVING_PORT"
	PortSpecification string `json:"portSpecification,omitempty"`

	// ProxyHeader: Specifies the type of proxy header to append before
	// sending data to the backend, either NONE or PROXY_V1. The default is
	// NONE.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// RequestPath: The request path of the HTTP/2 health check request. The
	// default value is /.
	RequestPath string `json:"requestPath,omitempty"`

	// Response: The string to match anywhere in the first 1024 bytes of the
	// response body. If left empty (the default value), the status code
	// determines health. The response data can only be ASCII.
	Response string `json:"response,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Host") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Host") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HTTP2HealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod HTTP2HealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HTTPHealthCheck struct {
	// Host: The value of the host header in the HTTP health check request.
	// If left empty (default value), the IP on behalf of which this health
	// check is performed will be used.
	Host string `json:"host,omitempty"`

	// Port: The TCP port number for the health check request. The default
	// value is 80. Valid values are 1 through 65535.
	Port int64 `json:"port,omitempty"`

	// PortName: Port name as defined in InstanceGroup#NamedPort#name. If
	// both port and port_name are defined, port takes precedence.
	PortName string `json:"portName,omitempty"`

	// PortSpecification: Specifies how port is selected for health
	// checking, can be one of following values:
	// USE_FIXED_PORT: The port number in
	// port
	// is used for health checking.
	// USE_NAMED_PORT: The
	// portName
	// is used for health checking.
	// USE_SERVING_PORT: For NetworkEndpointGroup, the port specified for
	// each network endpoint is used for health checking. For other
	// backends, the port or named port specified in the Backend Service is
	// used for health checking.
	//
	//
	// If not specified, HTTP health check follows behavior specified
	// in
	// port
	// and
	// portName
	// fields.
	//
	// Possible values:
	//   "USE_FIXED_PORT"
	//   "USE_NAMED_PORT"
	//   "USE_SERVING_PORT"
	PortSpecification string `json:"portSpecification,omitempty"`

	// ProxyHeader: Specifies the type of proxy header to append before
	// sending data to the backend, either NONE or PROXY_V1. The default is
	// NONE.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// RequestPath: The request path of the HTTP health check request. The
	// default value is /.
	RequestPath string `json:"requestPath,omitempty"`

	// Response: The string to match anywhere in the first 1024 bytes of the
	// response body. If left empty (the default value), the status code
	// determines health. The response data can only be ASCII.
	Response string `json:"response,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Host") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Host") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HTTPHealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod HTTPHealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HTTPSHealthCheck struct {
	// Host: The value of the host header in the HTTPS health check request.
	// If left empty (default value), the IP on behalf of which this health
	// check is performed will be used.
	Host string `json:"host,omitempty"`

	// Port: The TCP port number for the health check request. The default
	// value is 443. Valid values are 1 through 65535.
	Port int64 `json:"port,omitempty"`

	// PortName: Port name as defined in InstanceGroup#NamedPort#name. If
	// both port and port_name are defined, port takes precedence.
	PortName string `json:"portName,omitempty"`

	// PortSpecification: Specifies how port is selected for health
	// checking, can be one of following values:
	// USE_FIXED_PORT: The port number in
	// port
	// is used for health checking.
	// USE_NAMED_PORT: The
	// portName
	// is used for health checking.
	// USE_SERVING_PORT: For NetworkEndpointGroup, the port specified for
	// each network endpoint is used for health checking. For other
	// backends, the port or named port specified in the Backend Service is
	// used for health checking.
	//
	//
	// If not specified, HTTPS health check follows behavior specified
	// in
	// port
	// and
	// portName
	// fields.
	//
	// Possible values:
	//   "USE_FIXED_PORT"
	//   "USE_NAMED_PORT"
	//   "USE_SERVING_PORT"
	PortSpecification string `json:"portSpecification,omitempty"`

	// ProxyHeader: Specifies the type of proxy header to append before
	// sending data to the backend, either NONE or PROXY_V1. The default is
	// NONE.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// RequestPath: The request path of the HTTPS health check request. The
	// default value is /.
	RequestPath string `json:"requestPath,omitempty"`

	// Response: The string to match anywhere in the first 1024 bytes of the
	// response body. If left empty (the default value), the status code
	// determines health. The response data can only be ASCII.
	Response string `json:"response,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Host") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Host") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HTTPSHealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod HTTPSHealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HealthCheck: Represents a Health Check resource.
//
// Health checks are used for most GCP load balancers and managed
// instance group auto-healing. For more information, read Health Check
// Concepts.
//
// To perform health checks on network load balancers, you must use
// either httpHealthChecks or httpsHealthChecks.
type HealthCheck struct {
	// CheckIntervalSec: How often (in seconds) to send a health check. The
	// default value is 5 seconds.
	CheckIntervalSec int64 `json:"checkIntervalSec,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in 3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// HealthyThreshold: A so-far unhealthy instance will be marked healthy
	// after this many consecutive successes. The default value is 2.
	HealthyThreshold int64 `json:"healthyThreshold,omitempty"`

	Http2HealthCheck *HTTP2HealthCheck `json:"http2HealthCheck,omitempty"`

	HttpHealthCheck *HTTPHealthCheck `json:"httpHealthCheck,omitempty"`

	HttpsHealthCheck *HTTPSHealthCheck `json:"httpsHealthCheck,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: Type of the resource.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Region: [Output Only] Region where the health check resides. Not
	// applicable to global health checks.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	SslHealthCheck *SSLHealthCheck `json:"sslHealthCheck,omitempty"`

	TcpHealthCheck *TCPHealthCheck `json:"tcpHealthCheck,omitempty"`

	// TimeoutSec: How long (in seconds) to wait before claiming failure.
	// The default value is 5 seconds. It is invalid for timeoutSec to have
	// greater value than checkIntervalSec.
	TimeoutSec int64 `json:"timeoutSec,omitempty"`

	// Type: Specifies the type of the healthCheck, either TCP, SSL, HTTP,
	// HTTPS or HTTP2. If not specified, the default is TCP. Exactly one of
	// the protocol-specific health check field must be specified, which
	// must match type field.
	//
	// Possible values:
	//   "HTTP"
	//   "HTTP2"
	//   "HTTPS"
	//   "INVALID"
	//   "SSL"
	//   "TCP"
	Type string `json:"type,omitempty"`

	// UnhealthyThreshold: A so-far healthy instance will be marked
	// unhealthy after this many consecutive failures. The default value is
	// 2.
	UnhealthyThreshold int64 `json:"unhealthyThreshold,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CheckIntervalSec") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CheckIntervalSec") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *HealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod HealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HealthCheckList: Contains a list of HealthCheck resources.
type HealthCheckList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of HealthCheck resources.
	Items []*HealthCheck `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *HealthCheckListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthCheckList) MarshalJSON() ([]byte, error) {
	type NoMethod HealthCheckList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HealthCheckListWarning: [Output Only] Informational warning message.
type HealthCheckListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*HealthCheckListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthCheckListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod HealthCheckListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HealthCheckListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthCheckListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod HealthCheckListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HealthCheckReference: A full or valid partial URL to a health check.
// For example, the following are valid URLs:
// -
// https://www.googleapis.com/compute/beta/projects/project-id/global/httpHealthChecks/health-check
// - projects/project-id/global/httpHealthChecks/health-check
// - global/httpHealthChecks/health-check
type HealthCheckReference struct {
	HealthCheck string `json:"healthCheck,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HealthCheck") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthCheck") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthCheckReference) MarshalJSON() ([]byte, error) {
	type NoMethod HealthCheckReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HealthChecksAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of HealthChecksScopedList resources.
	Items map[string]HealthChecksScopedList `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *HealthChecksAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthChecksAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod HealthChecksAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HealthChecksAggregatedListWarning: [Output Only] Informational
// warning message.
type HealthChecksAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*HealthChecksAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthChecksAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod HealthChecksAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HealthChecksAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthChecksAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod HealthChecksAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HealthChecksScopedList struct {
	// HealthChecks: A list of HealthChecks contained in this scope.
	HealthChecks []*HealthCheck `json:"healthChecks,omitempty"`

	// Warning: Informational warning which replaces the list of backend
	// services when the list is empty.
	Warning *HealthChecksScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HealthChecks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthChecks") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthChecksScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod HealthChecksScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HealthChecksScopedListWarning: Informational warning which replaces
// the list of backend services when the list is empty.
type HealthChecksScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*HealthChecksScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthChecksScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod HealthChecksScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HealthChecksScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthChecksScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod HealthChecksScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HealthStatus struct {
	// HealthState: Health state of the instance.
	//
	// Possible values:
	//   "HEALTHY"
	//   "UNHEALTHY"
	HealthState string `json:"healthState,omitempty"`

	// Instance: URL of the instance resource.
	Instance string `json:"instance,omitempty"`

	// IpAddress: The IP address represented by this resource.
	IpAddress string `json:"ipAddress,omitempty"`

	// Port: The port on the instance.
	Port int64 `json:"port,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HealthState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HealthStatus) MarshalJSON() ([]byte, error) {
	type NoMethod HealthStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HealthStatusForNetworkEndpoint struct {
	// BackendService: URL of the backend service associated with the health
	// state of the network endpoint.
	BackendService *BackendServiceReference `json:"backendService,omitempty"`

	// ForwardingRule: URL of the forwarding rule associated with the health
	// state of the network endpoint.
	ForwardingRule *ForwardingRuleReference `json:"forwardingRule,omitempty"`

	// HealthCheck: URL of the health check associated with the health state
	// of the network endpoint.
	HealthCheck *HealthCheckReference `json:"healthCheck,omitempty"`

	// HealthState: Health state of the network endpoint determined based on
	// the health checks configured.
	//
	// Possible values:
	//   "DRAINING"
	//   "HEALTHY"
	//   "UNHEALTHY"
	//   "UNKNOWN"
	HealthState string `json:"healthState,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackendService") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackendService") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *HealthStatusForNetworkEndpoint) MarshalJSON() ([]byte, error) {
	type NoMethod HealthStatusForNetworkEndpoint
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HostRule: UrlMaps A host-matching rule for a URL. If matched, will
// use the named PathMatcher to select the BackendService.
type HostRule struct {
	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Hosts: The list of host patterns to match. They must be valid
	// hostnames, except * will match any string of ([a-z0-9-.]*). In that
	// case, * must be the first character and must be followed in the
	// pattern by either - or ..
	Hosts []string `json:"hosts,omitempty"`

	// PathMatcher: The name of the PathMatcher to use to match the path
	// portion of the URL if the hostRule matches the URL's host portion.
	PathMatcher string `json:"pathMatcher,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HostRule) MarshalJSON() ([]byte, error) {
	type NoMethod HostRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpFaultAbort: Specification for how requests are aborted as part of
// fault injection.
type HttpFaultAbort struct {
	// HttpStatus: The HTTP status code used to abort the request.
	// The value must be between 200 and 599 inclusive.
	HttpStatus int64 `json:"httpStatus,omitempty"`

	// Percentage: The percentage of traffic
	// (connections/operations/requests) which will be aborted as part of
	// fault injection.
	// The value must be between 0.0 and 100.0 inclusive.
	Percentage float64 `json:"percentage,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HttpStatus") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HttpStatus") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpFaultAbort) MarshalJSON() ([]byte, error) {
	type NoMethod HttpFaultAbort
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *HttpFaultAbort) UnmarshalJSON(data []byte) error {
	type NoMethod HttpFaultAbort
	var s1 struct {
		Percentage gensupport.JSONFloat64 `json:"percentage"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Percentage = float64(s1.Percentage)
	return nil
}

// HttpFaultDelay: Specifies the delay introduced by Loadbalancer before
// forwarding the request to the backend service as part of fault
// injection.
type HttpFaultDelay struct {
	// FixedDelay: Specifies the value of the fixed delay interval.
	FixedDelay *Duration `json:"fixedDelay,omitempty"`

	// Percentage: The percentage of traffic
	// (connections/operations/requests) on which delay will be introduced
	// as part of fault injection.
	// The value must be between 0.0 and 100.0 inclusive.
	Percentage float64 `json:"percentage,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FixedDelay") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "FixedDelay") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpFaultDelay) MarshalJSON() ([]byte, error) {
	type NoMethod HttpFaultDelay
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *HttpFaultDelay) UnmarshalJSON(data []byte) error {
	type NoMethod HttpFaultDelay
	var s1 struct {
		Percentage gensupport.JSONFloat64 `json:"percentage"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Percentage = float64(s1.Percentage)
	return nil
}

// HttpFaultInjection: The specification for fault injection introduced
// into traffic to test the resiliency of clients to backend service
// failure. As part of fault injection, when clients send requests to a
// backend service, delays can be introduced by Loadbalancer on a
// percentage of requests before sending those request to the backend
// service. Similarly requests from clients can be aborted by the
// Loadbalancer for a percentage of requests.
type HttpFaultInjection struct {
	// Abort: The specification for how client requests are aborted as part
	// of fault injection.
	Abort *HttpFaultAbort `json:"abort,omitempty"`

	// Delay: The specification for how client requests are delayed as part
	// of fault injection, before being sent to a backend service.
	Delay *HttpFaultDelay `json:"delay,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Abort") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Abort") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpFaultInjection) MarshalJSON() ([]byte, error) {
	type NoMethod HttpFaultInjection
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpHeaderAction: The request and response header transformations
// that take effect before the request is passed along to the selected
// backendService.
type HttpHeaderAction struct {
	// RequestHeadersToAdd: Headers to add to a matching request prior to
	// forwarding the request to the backendService.
	RequestHeadersToAdd []*HttpHeaderOption `json:"requestHeadersToAdd,omitempty"`

	// RequestHeadersToRemove: A list of header names for headers that need
	// to be removed from the request prior to forwarding the request to the
	// backendService.
	RequestHeadersToRemove []string `json:"requestHeadersToRemove,omitempty"`

	// ResponseHeadersToAdd: Headers to add the response prior to sending
	// the response back to the client.
	ResponseHeadersToAdd []*HttpHeaderOption `json:"responseHeadersToAdd,omitempty"`

	// ResponseHeadersToRemove: A list of header names for headers that need
	// to be removed from the response prior to sending the response back to
	// the client.
	ResponseHeadersToRemove []string `json:"responseHeadersToRemove,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RequestHeadersToAdd")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RequestHeadersToAdd") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *HttpHeaderAction) MarshalJSON() ([]byte, error) {
	type NoMethod HttpHeaderAction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpHeaderMatch: matchRule criteria for request header matches.
type HttpHeaderMatch struct {
	// ExactMatch: The value should exactly match contents of
	// exactMatch.
	// Only one of exactMatch, prefixMatch, suffixMatch, regexMatch,
	// presentMatch or rangeMatch must be set.
	ExactMatch string `json:"exactMatch,omitempty"`

	// HeaderName: The name of the HTTP header to match.
	// For matching against the HTTP request's authority, use a headerMatch
	// with the header name ":authority".
	// For matching a request's method, use the headerName ":method".
	HeaderName string `json:"headerName,omitempty"`

	// InvertMatch: If set to false, the headerMatch is considered a match
	// if the match criteria above are met. If set to true, the headerMatch
	// is considered a match if the match criteria above are NOT met.
	// The default setting is false.
	InvertMatch bool `json:"invertMatch,omitempty"`

	// PrefixMatch: The value of the header must start with the contents of
	// prefixMatch.
	// Only one of exactMatch, prefixMatch, suffixMatch, regexMatch,
	// presentMatch or rangeMatch must be set.
	PrefixMatch string `json:"prefixMatch,omitempty"`

	// PresentMatch: A header with the contents of headerName must exist.
	// The match takes place whether or not the request's header has a value
	// or not.
	// Only one of exactMatch, prefixMatch, suffixMatch, regexMatch,
	// presentMatch or rangeMatch must be set.
	PresentMatch bool `json:"presentMatch,omitempty"`

	// RangeMatch: The header value must be an integer and its value must be
	// in the range specified in rangeMatch. If the header does not contain
	// an integer, number or is empty, the match fails.
	// For example for a range [-5, 0]
	// - -3 will match.
	// - 0 will not match.
	// - 0.25 will not match.
	// - -3someString will not match.
	// Only one of exactMatch, prefixMatch, suffixMatch, regexMatch,
	// presentMatch or rangeMatch must be set.
	RangeMatch *Int64RangeMatch `json:"rangeMatch,omitempty"`

	// RegexMatch: The value of the header must match the regualar
	// expression specified in regexMatch. For regular expression grammar,
	// please see:  en.cppreference.com/w/cpp/regex/ecmascript
	// For matching against a port specified in the HTTP request, use a
	// headerMatch with headerName set to PORT and a regular expression that
	// satisfies the RFC2616 Host header's port specifier.
	// Only one of exactMatch, prefixMatch, suffixMatch, regexMatch,
	// presentMatch or rangeMatch must be set.
	RegexMatch string `json:"regexMatch,omitempty"`

	// SuffixMatch: The value of the header must end with the contents of
	// suffixMatch.
	// Only one of exactMatch, prefixMatch, suffixMatch, regexMatch,
	// presentMatch or rangeMatch must be set.
	SuffixMatch string `json:"suffixMatch,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExactMatch") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExactMatch") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpHeaderMatch) MarshalJSON() ([]byte, error) {
	type NoMethod HttpHeaderMatch
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpHeaderOption: Specification determining how headers are added to
// requests or responses.
type HttpHeaderOption struct {
	// HeaderName: The name of the header.
	HeaderName string `json:"headerName,omitempty"`

	// HeaderValue: The value of the header to add.
	HeaderValue string `json:"headerValue,omitempty"`

	// Replace: If false, headerValue is appended to any values that already
	// exist for the header. If true, headerValue is set for the header,
	// discarding any values that were set for that header.
	// The default value is false.
	Replace bool `json:"replace,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HeaderName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HeaderName") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpHeaderOption) MarshalJSON() ([]byte, error) {
	type NoMethod HttpHeaderOption
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpHealthCheck: Represents a legacy HTTP Health Check
// resource.
//
// Legacy health checks are required by network load balancers. For more
// information, read Health Check Concepts.
type HttpHealthCheck struct {
	// CheckIntervalSec: How often (in seconds) to send a health check. The
	// default value is 5 seconds.
	CheckIntervalSec int64 `json:"checkIntervalSec,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// HealthyThreshold: A so-far unhealthy instance will be marked healthy
	// after this many consecutive successes. The default value is 2.
	HealthyThreshold int64 `json:"healthyThreshold,omitempty"`

	// Host: The value of the host header in the HTTP health check request.
	// If left empty (default value), the public IP on behalf of which this
	// health check is performed will be used.
	Host string `json:"host,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#httpHealthCheck for HTTP health checks.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Port: The TCP port number for the HTTP health check request. The
	// default value is 80.
	Port int64 `json:"port,omitempty"`

	// RequestPath: The request path of the HTTP health check request. The
	// default value is /. This field does not support query parameters.
	RequestPath string `json:"requestPath,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// TimeoutSec: How long (in seconds) to wait before claiming failure.
	// The default value is 5 seconds. It is invalid for timeoutSec to have
	// greater value than checkIntervalSec.
	TimeoutSec int64 `json:"timeoutSec,omitempty"`

	// UnhealthyThreshold: A so-far healthy instance will be marked
	// unhealthy after this many consecutive failures. The default value is
	// 2.
	UnhealthyThreshold int64 `json:"unhealthyThreshold,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CheckIntervalSec") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CheckIntervalSec") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *HttpHealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod HttpHealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpHealthCheckList: Contains a list of HttpHealthCheck resources.
type HttpHealthCheckList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of HttpHealthCheck resources.
	Items []*HttpHealthCheck `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *HttpHealthCheckListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpHealthCheckList) MarshalJSON() ([]byte, error) {
	type NoMethod HttpHealthCheckList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpHealthCheckListWarning: [Output Only] Informational warning
// message.
type HttpHealthCheckListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*HttpHealthCheckListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpHealthCheckListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod HttpHealthCheckListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HttpHealthCheckListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpHealthCheckListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod HttpHealthCheckListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpQueryParameterMatch: HttpRouteRuleMatch criteria for a request's
// query parameter.
type HttpQueryParameterMatch struct {
	// ExactMatch: The queryParameterMatch matches if the value of the
	// parameter exactly matches the contents of exactMatch.
	// Only one of presentMatch, exactMatch and regexMatch must be set.
	ExactMatch string `json:"exactMatch,omitempty"`

	// Name: The name of the query parameter to match. The query parameter
	// must exist in the request, in the absence of which the request match
	// fails.
	Name string `json:"name,omitempty"`

	// PresentMatch: Specifies that the queryParameterMatch matches if the
	// request contains the query parameter, irrespective of whether the
	// parameter has a value or not.
	// Only one of presentMatch, exactMatch and regexMatch must be set.
	PresentMatch bool `json:"presentMatch,omitempty"`

	// RegexMatch: The queryParameterMatch matches if the value of the
	// parameter matches the regular expression specified by regexMatch. For
	// the regular expression grammar, please see
	// en.cppreference.com/w/cpp/regex/ecmascript
	// Only one of presentMatch, exactMatch and regexMatch must be set.
	RegexMatch string `json:"regexMatch,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExactMatch") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExactMatch") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpQueryParameterMatch) MarshalJSON() ([]byte, error) {
	type NoMethod HttpQueryParameterMatch
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpRedirectAction: Specifies settings for an HTTP redirect.
type HttpRedirectAction struct {
	// HostRedirect: The host that will be used in the redirect response
	// instead of the one that was supplied in the request.
	// The value must be between 1 and 255 characters.
	HostRedirect string `json:"hostRedirect,omitempty"`

	// HttpsRedirect: If set to true, the URL scheme in the redirected
	// request is set to https. If set to false, the URL scheme of the
	// redirected request will remain the same as that of the request.
	// This must only be set for UrlMaps used in TargetHttpProxys. Setting
	// this true for TargetHttpsProxy is not permitted.
	// The default is set to false.
	HttpsRedirect bool `json:"httpsRedirect,omitempty"`

	// PathRedirect: The path that will be used in the redirect response
	// instead of the one that was supplied in the request.
	// Only one of pathRedirect or prefixRedirect must be specified.
	// The value must be between 1 and 1024 characters.
	PathRedirect string `json:"pathRedirect,omitempty"`

	// PrefixRedirect: The prefix that replaces the prefixMatch specified in
	// the HttpRouteRuleMatch, retaining the remaining portion of the URL
	// before redirecting the request.
	PrefixRedirect string `json:"prefixRedirect,omitempty"`

	// RedirectResponseCode: The HTTP Status code to use for this
	// RedirectAction.
	// Supported values are:
	// - MOVED_PERMANENTLY_DEFAULT, which is the default value and
	// corresponds to 301.
	// - FOUND, which corresponds to 302.
	// - SEE_OTHER which corresponds to 303.
	// - TEMPORARY_REDIRECT, which corresponds to 307. In this case, the
	// request method will be retained.
	// - PERMANENT_REDIRECT, which corresponds to 308. In this case, the
	// request method will be retained.
	//
	// Possible values:
	//   "FOUND"
	//   "MOVED_PERMANENTLY_DEFAULT"
	//   "PERMANENT_REDIRECT"
	//   "SEE_OTHER"
	//   "TEMPORARY_REDIRECT"
	RedirectResponseCode string `json:"redirectResponseCode,omitempty"`

	// StripQuery: If set to true, any accompanying query portion of the
	// original URL is removed prior to redirecting the request. If set to
	// false, the query portion of the original URL is retained.
	// The default is set to false.
	StripQuery bool `json:"stripQuery,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HostRedirect") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HostRedirect") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpRedirectAction) MarshalJSON() ([]byte, error) {
	type NoMethod HttpRedirectAction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpRetryPolicy: The retry policy associates with HttpRouteRule
type HttpRetryPolicy struct {
	// NumRetries: Specifies the allowed number retries. This number must be
	// > 0. If not specified, defaults to 1.
	NumRetries int64 `json:"numRetries,omitempty"`

	// PerTryTimeout: Specifies a non-zero timeout per retry attempt.
	// If not specified, will use the timeout set in HttpRouteAction. If
	// timeout in HttpRouteAction is not set, will use the largest timeout
	// among all backend services associated with the route.
	PerTryTimeout *Duration `json:"perTryTimeout,omitempty"`

	// RetryConditions: Specfies one or more conditions when this retry rule
	// applies. Valid values are:
	// - 5xx: Loadbalancer will attempt a retry if the backend service
	// responds with any 5xx response code, or if the backend service does
	// not respond at all, example: disconnects, reset, read timeout,
	// connection failure, and refused streams.
	// - gateway-error: Similar to 5xx, but only applies to response codes
	// 502, 503 or 504.
	// -
	// - connect-failure: Loadbalancer will retry on failures connecting to
	// backend services, for example due to connection timeouts.
	// - retriable-4xx: Loadbalancer will retry for retriable 4xx response
	// codes. Currently the only retriable error supported is 409.
	// - refused-stream:Loadbalancer will retry if the backend service
	// resets the stream with a REFUSED_STREAM error code. This reset type
	// indicates that it is safe to retry.
	// - cancelledLoadbalancer will retry if the gRPC status code in the
	// response header is set to cancelled
	// - deadline-exceeded: Loadbalancer will retry if the gRPC status code
	// in the response header is set to deadline-exceeded
	// - resource-exhausted: Loadbalancer will retry if the gRPC status code
	// in the response header is set to resource-exhausted
	// - unavailable: Loadbalancer will retry if the gRPC status code in the
	// response header is set to unavailable
	RetryConditions []string `json:"retryConditions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NumRetries") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NumRetries") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpRetryPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod HttpRetryPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HttpRouteAction struct {
	// CorsPolicy: The specification for allowing client side cross-origin
	// requests. Please see W3C Recommendation for Cross Origin Resource
	// Sharing
	CorsPolicy *CorsPolicy `json:"corsPolicy,omitempty"`

	// FaultInjectionPolicy: The specification for fault injection
	// introduced into traffic to test the resiliency of clients to backend
	// service failure. As part of fault injection, when clients send
	// requests to a backend service, delays can be introduced by
	// Loadbalancer on a percentage of requests before sending those request
	// to the backend service. Similarly requests from clients can be
	// aborted by the Loadbalancer for a percentage of requests.
	// timeout and retry_policy will be ignored by clients that are
	// configured with a fault_injection_policy.
	FaultInjectionPolicy *HttpFaultInjection `json:"faultInjectionPolicy,omitempty"`

	// RequestMirrorPolicy: Specifies the policy on how requests intended
	// for the route's backends are shadowed to a separate mirrored backend
	// service. Loadbalancer does not wait for responses from the shadow
	// service. Prior to sending traffic to the shadow service, the host /
	// authority header is suffixed with -shadow.
	RequestMirrorPolicy *RequestMirrorPolicy `json:"requestMirrorPolicy,omitempty"`

	// RetryPolicy: Specifies the retry policy associated with this route.
	RetryPolicy *HttpRetryPolicy `json:"retryPolicy,omitempty"`

	// Timeout: Specifies the timeout for the selected route. Timeout is
	// computed from the time the request has been fully processed (i.e.
	// end-of-stream) up until the response has been completely processed.
	// Timeout includes all retries.
	// If not specified, will use the largest timeout among all backend
	// services associated with the route.
	Timeout *Duration `json:"timeout,omitempty"`

	// UrlRewrite: The spec to modify the URL of the request, prior to
	// forwarding the request to the matched service
	UrlRewrite *UrlRewrite `json:"urlRewrite,omitempty"`

	// WeightedBackendServices: A list of weighted backend services to send
	// traffic to when a route match occurs. The weights determine the
	// fraction of traffic that flows to their corresponding backend
	// service. If all traffic needs to go to a single backend service,
	// there must be one  weightedBackendService with weight set to a non 0
	// number.
	// Once a backendService is identified and before forwarding the request
	// to the backend service, advanced routing actions like Url rewrites
	// and header transformations are applied depending on additional
	// settings specified in this HttpRouteAction.
	WeightedBackendServices []*WeightedBackendService `json:"weightedBackendServices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CorsPolicy") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CorsPolicy") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpRouteAction) MarshalJSON() ([]byte, error) {
	type NoMethod HttpRouteAction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpRouteRule: An HttpRouteRule specifies how to match an HTTP
// request and the corresponding routing action that load balancing
// proxies will perform.
type HttpRouteRule struct {
	// Description: The short description conveying the intent of this
	// routeRule.
	// The description can have a maximum length of 1024 characters.
	Description string `json:"description,omitempty"`

	// HeaderAction: Specifies changes to request and response headers that
	// need to take effect for the selected backendService.
	// The headerAction specified here are applied before the matching
	// pathMatchers[].headerAction and after
	// pathMatchers[].routeRules[].routeAction.weightedBackendService.backend
	// ServiceWeightAction[].headerAction
	HeaderAction *HttpHeaderAction `json:"headerAction,omitempty"`

	MatchRules []*HttpRouteRuleMatch `json:"matchRules,omitempty"`

	// Priority: For routeRules within a given pathMatcher, priority
	// determines the order in which load balancer will interpret
	// routeRules. RouteRules are evaluated in order of priority, from the
	// lowest to highest number. The priority of a rule decreases as its
	// number increases (1, 2, 3, N+1). The first rule that matches the
	// request is applied.
	// You cannot configure two or more routeRules with the same priority.
	// Priority for each rule must be set to a number between 0 and
	// 2147483647 inclusive.
	// Priority numbers can have gaps, which enable you to add or remove
	// rules in the future without affecting the rest of the rules. For
	// example, 1, 2, 3, 4, 5, 9, 12, 16 is a valid series of priority
	// numbers to which you could add rules numbered from 6 to 8, 10 to 11,
	// and 13 to 15 in the future without any impact on existing rules.
	Priority int64 `json:"priority,omitempty"`

	// RouteAction: In response to a matching matchRule, the load balancer
	// performs advanced routing actions like URL rewrites, header
	// transformations, etc. prior to forwarding the request to the selected
	// backend. If  routeAction specifies any  weightedBackendServices,
	// service must not be set. Conversely if service is set, routeAction
	// cannot contain any  weightedBackendServices.
	// Only one of routeAction or urlRedirect must be set.
	RouteAction *HttpRouteAction `json:"routeAction,omitempty"`

	// Service: The full or partial URL of the backend service resource to
	// which traffic is directed if this rule is matched. If routeAction is
	// additionally specified, advanced routing actions like URL Rewrites,
	// etc. take effect prior to sending the request to the backend.
	// However, if service is specified, routeAction cannot contain any
	// weightedBackendService s. Conversely, if routeAction specifies any
	// weightedBackendServices, service must not be specified.
	// Only one of urlRedirect, service or
	// routeAction.weightedBackendService must be set.
	Service string `json:"service,omitempty"`

	// UrlRedirect: When this rule is matched, the request is redirected to
	// a URL specified by urlRedirect.
	// If urlRedirect is specified, service or routeAction must not be set.
	UrlRedirect *HttpRedirectAction `json:"urlRedirect,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpRouteRule) MarshalJSON() ([]byte, error) {
	type NoMethod HttpRouteRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpRouteRuleMatch: HttpRouteRuleMatch specifies a set of criteria
// for matching requests to an HttpRouteRule. All specified criteria
// must be satisfied for a match to occur.
type HttpRouteRuleMatch struct {
	// FullPathMatch: For satifying the matchRule condition, the path of the
	// request must exactly match the value specified in fullPathMatch after
	// removing any query parameters and anchor that may be part of the
	// original URL.
	// FullPathMatch must be between 1 and 1024 characters.
	// Only one of prefixMatch, fullPathMatch or regexMatch must be
	// specified.
	FullPathMatch string `json:"fullPathMatch,omitempty"`

	// HeaderMatches: Specifies a list of header match criteria, all of
	// which must match corresponding headers in the request.
	HeaderMatches []*HttpHeaderMatch `json:"headerMatches,omitempty"`

	// IgnoreCase: Specifies that prefixMatch and fullPathMatch matches are
	// case sensitive.
	// The default value is false.
	// caseSensitive must not be used with regexMatch.
	IgnoreCase bool `json:"ignoreCase,omitempty"`

	// MetadataFilters: Opaque filter criteria used by Loadbalancer to
	// restrict routing configuration to a limited set xDS compliant
	// clients. In their xDS requests to Loadbalancer, xDS clients present
	// node metadata. If a match takes place, the relevant routing
	// configuration is made available to those proxies.
	// For each metadataFilter in this list, if its filterMatchCriteria is
	// set to MATCH_ANY, at least one of the filterLabels must match the
	// corresponding label provided in the metadata. If its
	// filterMatchCriteria is set to MATCH_ALL, then all of its filterLabels
	// must match with corresponding labels in the provided
	// metadata.
	// metadataFilters specified here can be overrides those specified in
	// ForwardingRule that refers to this UrlMap.
	// metadataFilters only applies to Loadbalancers that have their
	// loadBalancingScheme set to INTERNAL_SELF_MANAGED.
	MetadataFilters []*MetadataFilter `json:"metadataFilters,omitempty"`

	// PrefixMatch: For satifying the matchRule condition, the request's
	// path must begin with the specified prefixMatch. prefixMatch must
	// begin with a /.
	// The value must be between 1 and 1024 characters.
	// Only one of prefixMatch, fullPathMatch or regexMatch must be
	// specified.
	PrefixMatch string `json:"prefixMatch,omitempty"`

	// QueryParameterMatches: Specifies a list of query parameter match
	// criteria, all of which must match corresponding query parameters in
	// the request.
	QueryParameterMatches []*HttpQueryParameterMatch `json:"queryParameterMatches,omitempty"`

	// RegexMatch: For satifying the matchRule condition, the path of the
	// request must satisfy the regular expression specified in regexMatch
	// after removing any query parameters and anchor supplied with the
	// original URL. For regular expression grammar please see
	// en.cppreference.com/w/cpp/regex/ecmascript
	// Only one of prefixMatch, fullPathMatch or regexMatch must be
	// specified.
	RegexMatch string `json:"regexMatch,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FullPathMatch") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "FullPathMatch") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpRouteRuleMatch) MarshalJSON() ([]byte, error) {
	type NoMethod HttpRouteRuleMatch
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpsHealthCheck: Represents a legacy HTTPS Health Check
// resource.
//
// Legacy health checks are required by network load balancers. For more
// information, read Health Check Concepts.
type HttpsHealthCheck struct {
	// CheckIntervalSec: How often (in seconds) to send a health check. The
	// default value is 5 seconds.
	CheckIntervalSec int64 `json:"checkIntervalSec,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// HealthyThreshold: A so-far unhealthy instance will be marked healthy
	// after this many consecutive successes. The default value is 2.
	HealthyThreshold int64 `json:"healthyThreshold,omitempty"`

	// Host: The value of the host header in the HTTPS health check request.
	// If left empty (default value), the public IP on behalf of which this
	// health check is performed will be used.
	Host string `json:"host,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: Type of the resource.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Port: The TCP port number for the HTTPS health check request. The
	// default value is 443.
	Port int64 `json:"port,omitempty"`

	// RequestPath: The request path of the HTTPS health check request. The
	// default value is "/".
	RequestPath string `json:"requestPath,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// TimeoutSec: How long (in seconds) to wait before claiming failure.
	// The default value is 5 seconds. It is invalid for timeoutSec to have
	// a greater value than checkIntervalSec.
	TimeoutSec int64 `json:"timeoutSec,omitempty"`

	// UnhealthyThreshold: A so-far healthy instance will be marked
	// unhealthy after this many consecutive failures. The default value is
	// 2.
	UnhealthyThreshold int64 `json:"unhealthyThreshold,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CheckIntervalSec") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CheckIntervalSec") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *HttpsHealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod HttpsHealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpsHealthCheckList: Contains a list of HttpsHealthCheck resources.
type HttpsHealthCheckList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of HttpsHealthCheck resources.
	Items []*HttpsHealthCheck `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *HttpsHealthCheckListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpsHealthCheckList) MarshalJSON() ([]byte, error) {
	type NoMethod HttpsHealthCheckList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpsHealthCheckListWarning: [Output Only] Informational warning
// message.
type HttpsHealthCheckListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*HttpsHealthCheckListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpsHealthCheckListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod HttpsHealthCheckListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HttpsHealthCheckListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpsHealthCheckListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod HttpsHealthCheckListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Image: Represents an Image resource.
//
// You can use images to create boot disks for your VM instances. For
// more information, read Images. (== resource_for beta.images ==) (==
// resource_for v1.images ==)
type Image struct {
	// ArchiveSizeBytes: Size of the image tar.gz archive stored in Google
	// Cloud Storage (in bytes).
	ArchiveSizeBytes int64 `json:"archiveSizeBytes,omitempty,string"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Deprecated: The deprecation status associated with this image.
	Deprecated *DeprecationStatus `json:"deprecated,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// DiskSizeGb: Size of the image when restored onto a persistent disk
	// (in GB).
	DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"`

	// Family: The name of the image family to which this image belongs. You
	// can create disks by specifying an image family instead of a specific
	// image name. The image family always returns its latest image that is
	// not deprecated. The name of the image family must comply with
	// RFC1035.
	Family string `json:"family,omitempty"`

	// GuestOsFeatures: A list of features to enable on the guest operating
	// system. Applicable only for bootable images. Read  Enabling guest
	// operating system features to see a list of available options.
	GuestOsFeatures []*GuestOsFeature `json:"guestOsFeatures,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// ImageEncryptionKey: Encrypts the image using a customer-supplied
	// encryption key.
	//
	// After you encrypt an image with a customer-supplied key, you must
	// provide the same key if you use the image later (e.g. to create a
	// disk from the image).
	//
	// Customer-supplied encryption keys do not protect access to metadata
	// of the disk.
	//
	// If you do not provide an encryption key when creating the image, then
	// the disk will be encrypted using an automatically generated key and
	// you do not need to provide a key to use the image later.
	ImageEncryptionKey *CustomerEncryptionKey `json:"imageEncryptionKey,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#image for
	// images.
	Kind string `json:"kind,omitempty"`

	// LabelFingerprint: A fingerprint for the labels being applied to this
	// image, which is essentially a hash of the labels used for optimistic
	// locking. The fingerprint is initially generated by Compute Engine and
	// changes after every request to modify or update labels. You must
	// always provide an up-to-date fingerprint hash in order to update or
	// change labels, otherwise the request will fail with error 412
	// conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve an
	// image.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: Labels to apply to this image. These can be later modified by
	// the setLabels method.
	Labels map[string]string `json:"labels,omitempty"`

	// LicenseCodes: Integer license codes indicating which licenses are
	// attached to this image.
	LicenseCodes googleapi.Int64s `json:"licenseCodes,omitempty"`

	// Licenses: Any applicable license URI.
	Licenses []string `json:"licenses,omitempty"`

	// Name: Name of the resource; provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// RawDisk: The parameters of the raw disk image.
	RawDisk *ImageRawDisk `json:"rawDisk,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SourceDisk: URL of the source disk used to create this image. This
	// can be a full or valid partial URL. You must provide either this
	// property or the rawDisk.source property but not both to create an
	// image. For example, the following are valid values:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/zones/zone/disks/disk
	// - projects/project/zones/zone/disks/disk
	// - zones/zone/disks/disk
	SourceDisk string `json:"sourceDisk,omitempty"`

	// SourceDiskEncryptionKey: The customer-supplied encryption key of the
	// source disk. Required if the source disk is protected by a
	// customer-supplied encryption key.
	SourceDiskEncryptionKey *CustomerEncryptionKey `json:"sourceDiskEncryptionKey,omitempty"`

	// SourceDiskId: [Output Only] The ID value of the disk used to create
	// this image. This value may be used to determine whether the image was
	// taken from the current or a previous instance of a given disk name.
	SourceDiskId string `json:"sourceDiskId,omitempty"`

	// SourceImage: URL of the source image used to create this image. This
	// can be a full or valid partial URL. You must provide exactly one of:
	//
	// - this property, or
	// - the rawDisk.source property, or
	// - the sourceDisk property   in order to create an image.
	SourceImage string `json:"sourceImage,omitempty"`

	// SourceImageEncryptionKey: The customer-supplied encryption key of the
	// source image. Required if the source image is protected by a
	// customer-supplied encryption key.
	SourceImageEncryptionKey *CustomerEncryptionKey `json:"sourceImageEncryptionKey,omitempty"`

	// SourceImageId: [Output Only] The ID value of the image used to create
	// this image. This value may be used to determine whether the image was
	// taken from the current or a previous instance of a given image name.
	SourceImageId string `json:"sourceImageId,omitempty"`

	// SourceSnapshot: URL of the source snapshot used to create this image.
	// This can be a full or valid partial URL. You must provide exactly one
	// of:
	// - this property, or
	// - the sourceImage property, or
	// - the rawDisk.source property, or
	// - the sourceDisk property   in order to create an image.
	SourceSnapshot string `json:"sourceSnapshot,omitempty"`

	// SourceSnapshotEncryptionKey: The customer-supplied encryption key of
	// the source snapshot. Required if the source snapshot is protected by
	// a customer-supplied encryption key.
	SourceSnapshotEncryptionKey *CustomerEncryptionKey `json:"sourceSnapshotEncryptionKey,omitempty"`

	// SourceSnapshotId: [Output Only] The ID value of the snapshot used to
	// create this image. This value may be used to determine whether the
	// snapshot was taken from the current or a previous instance of a given
	// snapshot name.
	SourceSnapshotId string `json:"sourceSnapshotId,omitempty"`

	// SourceType: The type of the image used to create this disk. The
	// default and only value is RAW
	//
	// Possible values:
	//   "RAW" (default)
	SourceType string `json:"sourceType,omitempty"`

	// Status: [Output Only] The status of the image. An image can be used
	// to create other resources, such as instances, only after the image
	// has been successfully created and the status is set to READY.
	// Possible values are FAILED, PENDING, or READY.
	//
	// Possible values:
	//   "DELETING"
	//   "FAILED"
	//   "PENDING"
	//   "READY"
	Status string `json:"status,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ArchiveSizeBytes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ArchiveSizeBytes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Image) MarshalJSON() ([]byte, error) {
	type NoMethod Image
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ImageRawDisk: The parameters of the raw disk image.
type ImageRawDisk struct {
	// ContainerType: The format used to encode and transmit the block
	// device, which should be TAR. This is just a container and
	// transmission format and not a runtime format. Provided by the client
	// when the disk image is created.
	//
	// Possible values:
	//   "TAR"
	ContainerType string `json:"containerType,omitempty"`

	// Sha1Checksum: [Deprecated] This field is deprecated. An optional SHA1
	// checksum of the disk image before unpackaging provided by the client
	// when the disk image is created.
	Sha1Checksum string `json:"sha1Checksum,omitempty"`

	// Source: The full Google Cloud Storage URL where the disk image is
	// stored. You must provide either this property or the sourceDisk
	// property but not both.
	Source string `json:"source,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContainerType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContainerType") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ImageRawDisk) MarshalJSON() ([]byte, error) {
	type NoMethod ImageRawDisk
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ImageList: Contains a list of images.
type ImageList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Image resources.
	Items []*Image `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ImageListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ImageList) MarshalJSON() ([]byte, error) {
	type NoMethod ImageList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ImageListWarning: [Output Only] Informational warning message.
type ImageListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ImageListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ImageListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ImageListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ImageListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ImageListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ImageListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Instance: Represents an Instance resource.
//
// An instance is a virtual machine that is hosted on Google Cloud
// Platform. For more information, read Virtual Machine Instances. (==
// resource_for beta.instances ==) (== resource_for v1.instances ==)
type Instance struct {
	// CanIpForward: Allows this instance to send and receive packets with
	// non-matching destination or source IPs. This is required if you plan
	// to use this instance to forward routes. For more information, see
	// Enabling IP Forwarding.
	CanIpForward bool `json:"canIpForward,omitempty"`

	// CpuPlatform: [Output Only] The CPU platform used by this instance.
	CpuPlatform string `json:"cpuPlatform,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// DeletionProtection: Whether the resource should be protected against
	// deletion.
	DeletionProtection bool `json:"deletionProtection,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Disks: Array of disks associated with this instance. Persistent disks
	// must be created before you can assign them.
	Disks []*AttachedDisk `json:"disks,omitempty"`

	// DisplayDevice: Enables display device for the instance.
	DisplayDevice *DisplayDevice `json:"displayDevice,omitempty"`

	// GuestAccelerators: A list of the type and count of accelerator cards
	// attached to the instance.
	GuestAccelerators []*AcceleratorConfig `json:"guestAccelerators,omitempty"`

	// Hostname: Specifies the hostname of the instance. The specified
	// hostname must be RFC1035 compliant. If hostname is not specified, the
	// default hostname is [INSTANCE_NAME].c.[PROJECT_ID].internal when
	// using the global DNS, and
	// [INSTANCE_NAME].[ZONE].c.[PROJECT_ID].internal when using zonal DNS.
	Hostname string `json:"hostname,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#instance for
	// instances.
	Kind string `json:"kind,omitempty"`

	// LabelFingerprint: A fingerprint for this request, which is
	// essentially a hash of the label's contents and used for optimistic
	// locking. The fingerprint is initially generated by Compute Engine and
	// changes after every request to modify or update labels. You must
	// always provide an up-to-date fingerprint hash in order to update or
	// change labels.
	//
	// To see the latest fingerprint, make get() request to the instance.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: Labels to apply to this instance. These can be later modified
	// by the setLabels method.
	Labels map[string]string `json:"labels,omitempty"`

	// MachineType: Full or partial URL of the machine type resource to use
	// for this instance, in the format:
	// zones/zone/machineTypes/machine-type. This is provided by the client
	// when the instance is created. For example, the following is a valid
	// partial url to a predefined machine
	// type:
	// zones/us-central1-f/machineTypes/n1-standard-1
	//
	//
	// To create a custom machine type, provide a URL to a machine type in
	// the following format, where CPUS is 1 or an even number up to 32 (2,
	// 4, 6, ... 24, etc), and MEMORY is the total memory for this instance.
	// Memory must be a multiple of 256 MB and must be supplied in MB (e.g.
	// 5 GB of memory is 5120
	// MB):
	// zones/zone/machineTypes/custom-CPUS-MEMORY
	//
	//
	// For example: zones/us-central1-f/machineTypes/custom-4-5120
	//
	// For a full list of restrictions, read the Specifications for custom
	// machine types.
	MachineType string `json:"machineType,omitempty"`

	// Metadata: The metadata key/value pairs assigned to this instance.
	// This includes custom metadata and predefined keys.
	Metadata *Metadata `json:"metadata,omitempty"`

	// MinCpuPlatform: Specifies a minimum CPU platform for the VM instance.
	// Applicable values are the friendly names of CPU platforms, such as
	// minCpuPlatform: "Intel Haswell" or minCpuPlatform: "Intel Sandy
	// Bridge".
	MinCpuPlatform string `json:"minCpuPlatform,omitempty"`

	// Name: The name of the resource, provided by the client when initially
	// creating the resource. The resource name must be 1-63 characters
	// long, and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	// NetworkInterfaces: An array of network configurations for this
	// instance. These specify how interfaces are configured to interact
	// with other network services, such as connecting to the internet.
	// Multiple interfaces are supported per instance.
	NetworkInterfaces []*NetworkInterface `json:"networkInterfaces,omitempty"`

	// ReservationAffinity: Specifies the reservations that this instance
	// can consume from.
	ReservationAffinity *ReservationAffinity `json:"reservationAffinity,omitempty"`

	// Scheduling: Sets the scheduling options for this instance.
	Scheduling *Scheduling `json:"scheduling,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServiceAccounts: A list of service accounts, with their specified
	// scopes, authorized for this instance. Only one service account per VM
	// instance is supported.
	//
	// Service accounts generate access tokens that can be accessed through
	// the metadata server and used to authenticate applications on the
	// instance. See Service Accounts for more information.
	ServiceAccounts []*ServiceAccount `json:"serviceAccounts,omitempty"`

	ShieldedInstanceConfig *ShieldedInstanceConfig `json:"shieldedInstanceConfig,omitempty"`

	ShieldedInstanceIntegrityPolicy *ShieldedInstanceIntegrityPolicy `json:"shieldedInstanceIntegrityPolicy,omitempty"`

	// StartRestricted: [Output Only] Whether a VM has been restricted for
	// start because Compute Engine has detected suspicious activity.
	StartRestricted bool `json:"startRestricted,omitempty"`

	// Status: [Output Only] The status of the instance. One of the
	// following values: PROVISIONING, STAGING, RUNNING, STOPPING, STOPPED,
	// SUSPENDING, SUSPENDED, and TERMINATED.
	//
	// Possible values:
	//   "PROVISIONING"
	//   "REPAIRING"
	//   "RUNNING"
	//   "STAGING"
	//   "STOPPED"
	//   "STOPPING"
	//   "SUSPENDED"
	//   "SUSPENDING"
	//   "TERMINATED"
	Status string `json:"status,omitempty"`

	// StatusMessage: [Output Only] An optional, human-readable explanation
	// of the status.
	StatusMessage string `json:"statusMessage,omitempty"`

	// Tags: Tags to apply to this instance. Tags are used to identify valid
	// sources or targets for network firewalls and are specified by the
	// client during instance creation. The tags can be later modified by
	// the setTags method. Each tag within the list must comply with
	// RFC1035. Multiple tags can be specified via the 'tags.items' field.
	Tags *Tags `json:"tags,omitempty"`

	// Zone: [Output Only] URL of the zone where the instance resides. You
	// must specify this field as part of the HTTP request URL. It is not
	// settable as a field in the request body.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CanIpForward") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CanIpForward") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Instance) MarshalJSON() ([]byte, error) {
	type NoMethod Instance
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: An object that contains a list of instances scoped by zone.
	Items map[string]InstancesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#instanceAggregatedList for aggregated lists of Instance
	// resources.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceAggregatedListWarning: [Output Only] Informational warning
// message.
type InstanceAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroup: Represents an unmanaged Instance Group resource.
//
// Use unmanaged instance groups if you need to apply load balancing to
// groups of heterogeneous instances or if you need to manage the
// instances yourself. For more information, read  Instance groups.
//
// For zonal unmanaged Instance Group, use instanceGroups resource.
//
// For regional unmanaged Instance Group, use regionInstanceGroups
// resource. (== resource_for beta.instanceGroups ==) (== resource_for
// v1.instanceGroups ==) (== resource_for beta.regionInstanceGroups ==)
// (== resource_for v1.regionInstanceGroups ==)
type InstanceGroup struct {
	// CreationTimestamp: [Output Only] The creation timestamp for this
	// instance group in RFC3339 text format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Fingerprint: [Output Only] The fingerprint of the named ports. The
	// system uses this fingerprint to detect conflicts when multiple users
	// change the named ports concurrently.
	Fingerprint string `json:"fingerprint,omitempty"`

	// Id: [Output Only] A unique identifier for this instance group,
	// generated by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroup for instance groups.
	Kind string `json:"kind,omitempty"`

	// Name: The name of the instance group. The name must be 1-63
	// characters long, and comply with RFC1035.
	Name string `json:"name,omitempty"`

	// NamedPorts: Assigns a name to a port number. For example: {name:
	// "http", port: 80}
	//
	// This allows the system to reference ports by the assigned name
	// instead of a port number. Named ports can also contain multiple
	// ports. For example: [{name: "http", port: 80},{name: "http", port:
	// 8080}]
	//
	// Named ports apply to all instances in this instance group.
	NamedPorts []*NamedPort `json:"namedPorts,omitempty"`

	// Network: The URL of the network to which all instances in the
	// instance group belong.
	Network string `json:"network,omitempty"`

	// Region: [Output Only] The URL of the region where the instance group
	// is located (for regional resources).
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] The URL for this instance group. The server
	// generates this URL.
	SelfLink string `json:"selfLink,omitempty"`

	// Size: [Output Only] The total number of instances in the instance
	// group.
	Size int64 `json:"size,omitempty"`

	// Subnetwork: [Output Only] The URL of the subnetwork to which all
	// instances in the instance group belong.
	Subnetwork string `json:"subnetwork,omitempty"`

	// Zone: [Output Only] The URL of the zone where the instance group is
	// located (for zonal resources).
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroup) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceGroupsScopedList resources.
	Items map[string]InstanceGroupsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroupAggregatedList for aggregated lists of instance
	// groups.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceGroupAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupAggregatedListWarning: [Output Only] Informational
// warning message.
type InstanceGroupAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceGroupAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupList: A list of InstanceGroup resources.
type InstanceGroupList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceGroup resources.
	Items []*InstanceGroup `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroupList for instance group lists.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceGroupListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupListWarning: [Output Only] Informational warning
// message.
type InstanceGroupListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceGroupListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupManager: Represents a Managed Instance Group
// resource.
//
// An instance group is a collection of VM instances that you can manage
// as a single entity. For more information, read Instance groups.
//
// For zonal Managed Instance Group, use the instanceGroupManagers
// resource.
//
// For regional Managed Instance Group, use the
// regionInstanceGroupManagers resource. (== resource_for
// beta.instanceGroupManagers ==) (== resource_for
// v1.instanceGroupManagers ==) (== resource_for
// beta.regionInstanceGroupManagers ==) (== resource_for
// v1.regionInstanceGroupManagers ==)
type InstanceGroupManager struct {
	// AutoHealingPolicies: The autohealing policy for this managed instance
	// group. You can specify only one value.
	AutoHealingPolicies []*InstanceGroupManagerAutoHealingPolicy `json:"autoHealingPolicies,omitempty"`

	// BaseInstanceName: The base instance name to use for instances in this
	// group. The value must be 1-58 characters long. Instances are named by
	// appending a hyphen and a random four-character string to the base
	// instance name. The base instance name must comply with RFC1035.
	BaseInstanceName string `json:"baseInstanceName,omitempty"`

	// CreationTimestamp: [Output Only] The creation timestamp for this
	// managed instance group in RFC3339 text format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// CurrentActions: [Output Only] The list of instance actions and the
	// number of instances in this managed instance group that are scheduled
	// for each of those actions.
	CurrentActions *InstanceGroupManagerActionsSummary `json:"currentActions,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// DistributionPolicy: Policy specifying intended distribution of
	// instances in regional managed instance group.
	DistributionPolicy *DistributionPolicy `json:"distributionPolicy,omitempty"`

	// Fingerprint: Fingerprint of this resource. This field may be used in
	// optimistic locking. It will be ignored when inserting an
	// InstanceGroupManager. An up-to-date fingerprint must be provided in
	// order to update the InstanceGroupManager, otherwise the request will
	// fail with error 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve an
	// InstanceGroupManager.
	Fingerprint string `json:"fingerprint,omitempty"`

	// Id: [Output Only] A unique identifier for this resource type. The
	// server generates this identifier.
	Id uint64 `json:"id,omitempty,string"`

	// InstanceGroup: [Output Only] The URL of the Instance Group resource.
	InstanceGroup string `json:"instanceGroup,omitempty"`

	// InstanceTemplate: The URL of the instance template that is specified
	// for this managed instance group. The group uses this template to
	// create all new instances in the managed instance group.
	InstanceTemplate string `json:"instanceTemplate,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroupManager for managed instance groups.
	Kind string `json:"kind,omitempty"`

	// Name: The name of the managed instance group. The name must be 1-63
	// characters long, and comply with RFC1035.
	Name string `json:"name,omitempty"`

	// NamedPorts: Named ports configured for the Instance Groups
	// complementary to this Instance Group Manager.
	NamedPorts []*NamedPort `json:"namedPorts,omitempty"`

	// Region: [Output Only] The URL of the region where the managed
	// instance group resides (for regional resources).
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] The URL for this managed instance group. The
	// server defines this URL.
	SelfLink string `json:"selfLink,omitempty"`

	// Status: [Output Only] The status of this managed instance group.
	Status *InstanceGroupManagerStatus `json:"status,omitempty"`

	// TargetPools: The URLs for all TargetPool resources to which instances
	// in the instanceGroup field are added. The target pools automatically
	// apply to all of the instances in the managed instance group.
	TargetPools []string `json:"targetPools,omitempty"`

	// TargetSize: The target number of running instances for this managed
	// instance group. Deleting or abandoning instances reduces this number.
	// Resizing the group changes this number.
	TargetSize int64 `json:"targetSize,omitempty"`

	// UpdatePolicy: The update policy for this managed instance group.
	UpdatePolicy *InstanceGroupManagerUpdatePolicy `json:"updatePolicy,omitempty"`

	// Versions: Specifies the instance templates used by this managed
	// instance group to create instances.
	//
	// Each version is defined by an instanceTemplate and a name. Every
	// version can appear at most once per instance group. This field
	// overrides the top-level instanceTemplate field. Read more about the
	// relationships between these fields. Exactly one version must leave
	// the targetSize field unset. That version will be applied to all
	// remaining instances. For more information, read about canary updates.
	Versions []*InstanceGroupManagerVersion `json:"versions,omitempty"`

	// Zone: [Output Only] The URL of the zone where the managed instance
	// group is located (for zonal resources).
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AutoHealingPolicies")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoHealingPolicies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManager) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManager
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerActionsSummary struct {
	// Abandoning: [Output Only] The total number of instances in the
	// managed instance group that are scheduled to be abandoned. Abandoning
	// an instance removes it from the managed instance group without
	// deleting it.
	Abandoning int64 `json:"abandoning,omitempty"`

	// Creating: [Output Only] The number of instances in the managed
	// instance group that are scheduled to be created or are currently
	// being created. If the group fails to create any of these instances,
	// it tries again until it creates the instance successfully.
	//
	// If you have disabled creation retries, this field will not be
	// populated; instead, the creatingWithoutRetries field will be
	// populated.
	Creating int64 `json:"creating,omitempty"`

	// CreatingWithoutRetries: [Output Only] The number of instances that
	// the managed instance group will attempt to create. The group attempts
	// to create each instance only once. If the group fails to create any
	// of these instances, it decreases the group's targetSize value
	// accordingly.
	CreatingWithoutRetries int64 `json:"creatingWithoutRetries,omitempty"`

	// Deleting: [Output Only] The number of instances in the managed
	// instance group that are scheduled to be deleted or are currently
	// being deleted.
	Deleting int64 `json:"deleting,omitempty"`

	// None: [Output Only] The number of instances in the managed instance
	// group that are running and have no scheduled actions.
	None int64 `json:"none,omitempty"`

	// Recreating: [Output Only] The number of instances in the managed
	// instance group that are scheduled to be recreated or are currently
	// being being recreated. Recreating an instance deletes the existing
	// root persistent disk and creates a new disk from the image that is
	// defined in the instance template.
	Recreating int64 `json:"recreating,omitempty"`

	// Refreshing: [Output Only] The number of instances in the managed
	// instance group that are being reconfigured with properties that do
	// not require a restart or a recreate action. For example, setting or
	// removing target pools for the instance.
	Refreshing int64 `json:"refreshing,omitempty"`

	// Restarting: [Output Only] The number of instances in the managed
	// instance group that are scheduled to be restarted or are currently
	// being restarted.
	Restarting int64 `json:"restarting,omitempty"`

	// Verifying: [Output Only] The number of instances in the managed
	// instance group that are being verified. See the
	// managedInstances[].currentAction property in the listManagedInstances
	// method documentation.
	Verifying int64 `json:"verifying,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Abandoning") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Abandoning") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerActionsSummary) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerActionsSummary
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceGroupManagersScopedList resources.
	Items map[string]InstanceGroupManagersScopedList `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroupManagerAggregatedList for an aggregated list of
	// managed instance groups.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceGroupManagerAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupManagerAggregatedListWarning: [Output Only]
// Informational warning message.
type InstanceGroupManagerAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceGroupManagerAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerAutoHealingPolicy struct {
	// HealthCheck: The URL for the health check that signals autohealing.
	HealthCheck string `json:"healthCheck,omitempty"`

	// InitialDelaySec: The number of seconds that the managed instance
	// group waits before it applies autohealing policies to new instances
	// or recently recreated instances. This initial delay allows instances
	// to initialize and run their startup scripts before the instance group
	// determines that they are UNHEALTHY. This prevents the managed
	// instance group from recreating its instances prematurely. This value
	// must be from range [0, 3600].
	InitialDelaySec int64 `json:"initialDelaySec,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HealthCheck") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthCheck") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerAutoHealingPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerAutoHealingPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupManagerList: [Output Only] A list of managed instance
// groups.
type InstanceGroupManagerList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceGroupManager resources.
	Items []*InstanceGroupManager `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroupManagerList for a list of managed instance
	// groups.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceGroupManagerListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupManagerListWarning: [Output Only] Informational warning
// message.
type InstanceGroupManagerListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceGroupManagerListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerStatus struct {
	// IsStable: [Output Only] A bit indicating whether the managed instance
	// group is in a stable state. A stable state means that: none of the
	// instances in the managed instance group is currently undergoing any
	// type of change (for example, creation, restart, or deletion); no
	// future changes are scheduled for instances in the managed instance
	// group; and the managed instance group itself is not being modified.
	IsStable bool `json:"isStable,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IsStable") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IsStable") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerStatus) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerUpdatePolicy struct {
	// MaxSurge: The maximum number of instances that can be created above
	// the specified targetSize during the update process. By default, a
	// fixed value of 1 is used. This value can be either a fixed number or
	// a percentage if the instance group has 10 or more instances. If you
	// set a percentage, the number of instances will be rounded up if
	// necessary.
	//
	// At least one of either maxSurge or maxUnavailable must be greater
	// than 0. Learn more about maxSurge.
	MaxSurge *FixedOrPercent `json:"maxSurge,omitempty"`

	// MaxUnavailable: The maximum number of instances that can be
	// unavailable during the update process. An instance is considered
	// available if all of the following conditions are satisfied:
	//
	//
	// - The instance's status is RUNNING.
	// - If there is a health check on the instance group, the instance's
	// liveness health check result must be HEALTHY at least once. If there
	// is no health check on the group, then the instance only needs to have
	// a status of RUNNING to be considered available.  By default, a fixed
	// value of 1 is used. This value can be either a fixed number or a
	// percentage if the instance group has 10 or more instances. If you set
	// a percentage, the number of instances will be rounded up if
	// necessary.
	//
	// At least one of either maxSurge or maxUnavailable must be greater
	// than 0. Learn more about maxUnavailable.
	MaxUnavailable *FixedOrPercent `json:"maxUnavailable,omitempty"`

	// MinimalAction: Minimal action to be taken on an instance. You can
	// specify either RESTART to restart existing instances or REPLACE to
	// delete and create new instances from the target template. If you
	// specify a RESTART, the Updater will attempt to perform that action
	// only. However, if the Updater determines that the minimal action you
	// specify is not enough to perform the update, it might perform a more
	// disruptive action.
	//
	// Possible values:
	//   "REPLACE"
	//   "RESTART"
	MinimalAction string `json:"minimalAction,omitempty"`

	// Type: The type of update process. You can specify either PROACTIVE so
	// that the instance group manager proactively executes actions in order
	// to bring instances to their target versions or OPPORTUNISTIC so that
	// no action is proactively executed but the update will be performed as
	// part of other actions (for example, resizes or recreateInstances
	// calls).
	//
	// Possible values:
	//   "OPPORTUNISTIC"
	//   "PROACTIVE"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MaxSurge") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MaxSurge") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerUpdatePolicy) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerUpdatePolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagerVersion struct {
	// InstanceTemplate: The URL of the instance template that is specified
	// for this managed instance group. The group uses this template to
	// create new instances in the managed instance group until the
	// `targetSize` for this version is reached.
	InstanceTemplate string `json:"instanceTemplate,omitempty"`

	// Name: Name of the version. Unique among all versions in the scope of
	// this managed instance group.
	Name string `json:"name,omitempty"`

	// TargetSize: Specifies the intended number of instances to be created
	// from the instanceTemplate. The final number of instances created from
	// the template will be equal to:
	// - If expressed as a fixed number, the minimum of either
	// targetSize.fixed or instanceGroupManager.targetSize is used.
	// - if expressed as a percent, the targetSize would be
	// (targetSize.percent/100 * InstanceGroupManager.targetSize) If there
	// is a remainder, the number is rounded up.  If unset, this version
	// will update any remaining instances not updated by another version.
	// Read Starting a canary update for more information.
	TargetSize *FixedOrPercent `json:"targetSize,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceTemplate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceTemplate") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagerVersion) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagerVersion
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersAbandonInstancesRequest struct {
	// Instances: The URLs of one or more instances to abandon. This can be
	// a full URL or a partial URL, such as
	// zones/[ZONE]/instances/[INSTANCE_NAME].
	Instances []string `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersAbandonInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersAbandonInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersDeleteInstancesRequest struct {
	// Instances: The URLs of one or more instances to delete. This can be a
	// full URL or a partial URL, such as
	// zones/[ZONE]/instances/[INSTANCE_NAME].
	Instances []string `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersDeleteInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersDeleteInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersListManagedInstancesResponse struct {
	// ManagedInstances: [Output Only] The list of instances in the managed
	// instance group.
	ManagedInstances []*ManagedInstance `json:"managedInstances,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ManagedInstances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ManagedInstances") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersListManagedInstancesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersListManagedInstancesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersRecreateInstancesRequest struct {
	// Instances: The URLs of one or more instances to recreate. This can be
	// a full URL or a partial URL, such as
	// zones/[ZONE]/instances/[INSTANCE_NAME].
	Instances []string `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersRecreateInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersRecreateInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersScopedList struct {
	// InstanceGroupManagers: [Output Only] The list of managed instance
	// groups that are contained in the specified project and zone.
	InstanceGroupManagers []*InstanceGroupManager `json:"instanceGroupManagers,omitempty"`

	// Warning: [Output Only] The warning that replaces the list of managed
	// instance groups when the list is empty.
	Warning *InstanceGroupManagersScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "InstanceGroupManagers") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceGroupManagers") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupManagersScopedListWarning: [Output Only] The warning
// that replaces the list of managed instance groups when the list is
// empty.
type InstanceGroupManagersScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceGroupManagersScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersSetInstanceTemplateRequest struct {
	// InstanceTemplate: The URL of the instance template that is specified
	// for this managed instance group. The group uses this template to
	// create all new instances in the managed instance group.
	InstanceTemplate string `json:"instanceTemplate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceTemplate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceTemplate") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersSetInstanceTemplateRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersSetInstanceTemplateRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupManagersSetTargetPoolsRequest struct {
	// Fingerprint: The fingerprint of the target pools information. Use
	// this optional property to prevent conflicts when multiple users
	// change the target pools settings concurrently. Obtain the fingerprint
	// with the instanceGroupManagers.get method. Then, include the
	// fingerprint in your request to ensure that you do not overwrite
	// changes that were applied from another concurrent request.
	Fingerprint string `json:"fingerprint,omitempty"`

	// TargetPools: The list of target pool URLs that instances in this
	// managed instance group belong to. The managed instance group applies
	// these target pools to all of the instances in the group. Existing
	// instances and new instances in the group all receive these target
	// pool settings.
	TargetPools []string `json:"targetPools,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fingerprint") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupManagersSetTargetPoolsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupManagersSetTargetPoolsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsAddInstancesRequest struct {
	// Instances: The list of instances to add to the instance group.
	Instances []*InstanceReference `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsAddInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsAddInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsListInstances struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceWithNamedPorts resources.
	Items []*InstanceWithNamedPorts `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroupsListInstances for the list of instances in the
	// specified instance group.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceGroupsListInstancesWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsListInstances) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsListInstances
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupsListInstancesWarning: [Output Only] Informational
// warning message.
type InstanceGroupsListInstancesWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceGroupsListInstancesWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsListInstancesWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsListInstancesWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsListInstancesWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsListInstancesWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsListInstancesWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsListInstancesRequest struct {
	// InstanceState: A filter for the state of the instances in the
	// instance group. Valid options are ALL or RUNNING. If you do not
	// specify this parameter the list includes all instances regardless of
	// their state.
	//
	// Possible values:
	//   "ALL"
	//   "RUNNING"
	InstanceState string `json:"instanceState,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsListInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsListInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsRemoveInstancesRequest struct {
	// Instances: The list of instances to remove from the instance group.
	Instances []*InstanceReference `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsRemoveInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsRemoveInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsScopedList struct {
	// InstanceGroups: [Output Only] The list of instance groups that are
	// contained in this scope.
	InstanceGroups []*InstanceGroup `json:"instanceGroups,omitempty"`

	// Warning: [Output Only] An informational warning that replaces the
	// list of instance groups when the list is empty.
	Warning *InstanceGroupsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceGroups") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceGroups") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceGroupsScopedListWarning: [Output Only] An informational
// warning that replaces the list of instance groups when the list is
// empty.
type InstanceGroupsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceGroupsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceGroupsSetNamedPortsRequest struct {
	// Fingerprint: The fingerprint of the named ports information for this
	// instance group. Use this optional property to prevent conflicts when
	// multiple users change the named ports settings concurrently. Obtain
	// the fingerprint with the instanceGroups.get method. Then, include the
	// fingerprint in your request to ensure that you do not overwrite
	// changes that were applied from another concurrent request. A request
	// with an incorrect fingerprint will fail with error 412
	// conditionNotMet.
	Fingerprint string `json:"fingerprint,omitempty"`

	// NamedPorts: The list of named ports to set for this instance group.
	NamedPorts []*NamedPort `json:"namedPorts,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fingerprint") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceGroupsSetNamedPortsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceGroupsSetNamedPortsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceList: Contains a list of instances.
type InstanceList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Instance resources.
	Items []*Instance `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#instanceList for
	// lists of Instance resources.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceListWarning: [Output Only] Informational warning message.
type InstanceListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceListReferrers: Contains a list of instance referrers.
type InstanceListReferrers struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Reference resources.
	Items []*Reference `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#instanceListReferrers for lists of Instance referrers.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceListReferrersWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceListReferrers) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceListReferrers
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceListReferrersWarning: [Output Only] Informational warning
// message.
type InstanceListReferrersWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceListReferrersWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceListReferrersWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceListReferrersWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceListReferrersWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceListReferrersWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceListReferrersWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceMoveRequest struct {
	// DestinationZone: The URL of the destination zone to move the
	// instance. This can be a full or partial URL. For example, the
	// following are all valid URLs to a zone:
	// - https://www.googleapis.com/compute/v1/projects/project/zones/zone
	//
	// - projects/project/zones/zone
	// - zones/zone
	DestinationZone string `json:"destinationZone,omitempty"`

	// TargetInstance: The URL of the target instance to move. This can be a
	// full or partial URL. For example, the following are all valid URLs to
	// an instance:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/zones/zone/instances/instance
	// - projects/project/zones/zone/instances/instance
	// - zones/zone/instances/instance
	TargetInstance string `json:"targetInstance,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DestinationZone") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DestinationZone") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceMoveRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceMoveRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceProperties struct {
	// CanIpForward: Enables instances created based on this template to
	// send packets with source IP addresses other than their own and
	// receive packets with destination IP addresses other than their own.
	// If these instances will be used as an IP gateway or it will be set as
	// the next-hop in a Route resource, specify true. If unsure, leave this
	// set to false. See the Enable IP forwarding documentation for more
	// information.
	CanIpForward bool `json:"canIpForward,omitempty"`

	// Description: An optional text description for the instances that are
	// created from this instance template.
	Description string `json:"description,omitempty"`

	// Disks: An array of disks that are associated with the instances that
	// are created from this template.
	Disks []*AttachedDisk `json:"disks,omitempty"`

	// GuestAccelerators: A list of guest accelerator cards' type and count
	// to use for instances created from the instance template.
	GuestAccelerators []*AcceleratorConfig `json:"guestAccelerators,omitempty"`

	// Labels: Labels to apply to instances that are created from this
	// template.
	Labels map[string]string `json:"labels,omitempty"`

	// MachineType: The machine type to use for instances that are created
	// from this template.
	MachineType string `json:"machineType,omitempty"`

	// Metadata: The metadata key/value pairs to assign to instances that
	// are created from this template. These pairs can consist of custom
	// metadata or predefined keys. See Project and instance metadata for
	// more information.
	Metadata *Metadata `json:"metadata,omitempty"`

	// MinCpuPlatform: Minimum cpu/platform to be used by this instance. The
	// instance may be scheduled on the specified or newer cpu/platform.
	// Applicable values are the friendly names of CPU platforms, such as
	// minCpuPlatform: "Intel Haswell" or minCpuPlatform: "Intel Sandy
	// Bridge". For more information, read Specifying a Minimum CPU
	// Platform.
	MinCpuPlatform string `json:"minCpuPlatform,omitempty"`

	// NetworkInterfaces: An array of network access configurations for this
	// interface.
	NetworkInterfaces []*NetworkInterface `json:"networkInterfaces,omitempty"`

	// ReservationAffinity: Specifies the reservations that this instance
	// can consume from.
	ReservationAffinity *ReservationAffinity `json:"reservationAffinity,omitempty"`

	// Scheduling: Specifies the scheduling options for the instances that
	// are created from this template.
	Scheduling *Scheduling `json:"scheduling,omitempty"`

	// ServiceAccounts: A list of service accounts with specified scopes.
	// Access tokens for these service accounts are available to the
	// instances that are created from this template. Use metadata queries
	// to obtain the access tokens for these instances.
	ServiceAccounts []*ServiceAccount `json:"serviceAccounts,omitempty"`

	ShieldedInstanceConfig *ShieldedInstanceConfig `json:"shieldedInstanceConfig,omitempty"`

	// Tags: A list of tags to apply to the instances that are created from
	// this template. The tags identify valid sources or targets for network
	// firewalls. The setTags method can modify this list of tags. Each tag
	// within the list must comply with RFC1035.
	Tags *Tags `json:"tags,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CanIpForward") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CanIpForward") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceProperties) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceReference struct {
	// Instance: The URL for a specific instance.
	Instance string `json:"instance,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instance") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instance") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceReference) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceTemplate: Represents an Instance Template resource.
//
// You can use instance templates to create VM instances and managed
// instance groups. For more information, read Instance Templates. (==
// resource_for beta.instanceTemplates ==) (== resource_for
// v1.instanceTemplates ==)
type InstanceTemplate struct {
	// CreationTimestamp: [Output Only] The creation timestamp for this
	// instance template in RFC3339 text format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] A unique identifier for this instance template. The
	// server defines this identifier.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceTemplate for instance templates.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource; provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Properties: The instance properties for this instance template.
	Properties *InstanceProperties `json:"properties,omitempty"`

	// SelfLink: [Output Only] The URL for this instance template. The
	// server defines this URL.
	SelfLink string `json:"selfLink,omitempty"`

	// SourceInstance: The source instance used to create the template. You
	// can provide this as a partial or full URL to the resource. For
	// example, the following are valid values:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/zones/zone/instances/instance
	// - projects/project/zones/zone/instances/instance
	SourceInstance string `json:"sourceInstance,omitempty"`

	// SourceInstanceParams: The source instance params to use to create
	// this instance template.
	SourceInstanceParams *SourceInstanceParams `json:"sourceInstanceParams,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstanceTemplate) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceTemplate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceTemplateList: A list of instance templates.
type InstanceTemplateList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceTemplate resources.
	Items []*InstanceTemplate `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceTemplatesListResponse for instance template lists.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InstanceTemplateListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceTemplateList) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceTemplateList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstanceTemplateListWarning: [Output Only] Informational warning
// message.
type InstanceTemplateListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstanceTemplateListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceTemplateListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceTemplateListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceTemplateListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceTemplateListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceTemplateListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstanceWithNamedPorts struct {
	// Instance: [Output Only] The URL of the instance.
	Instance string `json:"instance,omitempty"`

	// NamedPorts: [Output Only] The named ports that belong to this
	// instance group.
	NamedPorts []*NamedPort `json:"namedPorts,omitempty"`

	// Status: [Output Only] The status of the instance.
	//
	// Possible values:
	//   "PROVISIONING"
	//   "REPAIRING"
	//   "RUNNING"
	//   "STAGING"
	//   "STOPPED"
	//   "STOPPING"
	//   "SUSPENDED"
	//   "SUSPENDING"
	//   "TERMINATED"
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instance") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instance") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstanceWithNamedPorts) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceWithNamedPorts
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesScopedList struct {
	// Instances: [Output Only] A list of instances contained in this scope.
	Instances []*Instance `json:"instances,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of instances when the list is empty.
	Warning *InstancesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstancesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InstancesScopedListWarning: [Output Only] Informational warning which
// replaces the list of instances when the list is empty.
type InstancesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InstancesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstancesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstancesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesSetLabelsRequest struct {
	// LabelFingerprint: Fingerprint of the previous set of labels for this
	// resource, used to prevent conflicts. Provide the latest fingerprint
	// value when making a request to add or change labels.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	Labels map[string]string `json:"labels,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LabelFingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LabelFingerprint") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstancesSetLabelsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesSetLabelsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesSetMachineResourcesRequest struct {
	// GuestAccelerators: A list of the type and count of accelerator cards
	// attached to the instance.
	GuestAccelerators []*AcceleratorConfig `json:"guestAccelerators,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GuestAccelerators")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GuestAccelerators") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstancesSetMachineResourcesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesSetMachineResourcesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesSetMachineTypeRequest struct {
	// MachineType: Full or partial URL of the machine type resource. See
	// Machine Types for a full list of machine types. For example:
	// zones/us-central1-f/machineTypes/n1-standard-1
	MachineType string `json:"machineType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MachineType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MachineType") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstancesSetMachineTypeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesSetMachineTypeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesSetMinCpuPlatformRequest struct {
	// MinCpuPlatform: Minimum cpu/platform this instance should be started
	// at.
	MinCpuPlatform string `json:"minCpuPlatform,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MinCpuPlatform") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MinCpuPlatform") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InstancesSetMinCpuPlatformRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesSetMinCpuPlatformRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesSetServiceAccountRequest struct {
	// Email: Email address of the service account.
	Email string `json:"email,omitempty"`

	// Scopes: The list of scopes to be made available for this service
	// account.
	Scopes []string `json:"scopes,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Email") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Email") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstancesSetServiceAccountRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesSetServiceAccountRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InstancesStartWithEncryptionKeyRequest struct {
	// Disks: Array of disks associated with this instance that are
	// protected with a customer-supplied encryption key.
	//
	// In order to start the instance, the disk url and its corresponding
	// key must be provided.
	//
	// If the disk is not protected with a customer-supplied encryption key
	// it should not be specified.
	Disks []*CustomerEncryptionKeyProtectedDisk `json:"disks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Disks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Disks") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InstancesStartWithEncryptionKeyRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InstancesStartWithEncryptionKeyRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Int64RangeMatch: HttpRouteRuleMatch criteria for field values that
// must stay within the specified integer range.
type Int64RangeMatch struct {
	// RangeEnd: The end of the range (exclusive) in signed long integer
	// format.
	RangeEnd int64 `json:"rangeEnd,omitempty,string"`

	// RangeStart: The start of the range (inclusive) in signed long integer
	// format.
	RangeStart int64 `json:"rangeStart,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "RangeEnd") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RangeEnd") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Int64RangeMatch) MarshalJSON() ([]byte, error) {
	type NoMethod Int64RangeMatch
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Interconnect: Represents an Interconnect resource.
//
// An Interconnect resource is a dedicated connection between the GCP
// network and your on-premises network. For more information, read the
// Dedicated Interconnect Overview. (== resource_for v1.interconnects
// ==) (== resource_for beta.interconnects ==)
type Interconnect struct {
	// AdminEnabled: Administrative status of the interconnect. When this is
	// set to true, the Interconnect is functional and can carry traffic.
	// When set to false, no packets can be carried over the interconnect
	// and no BGP routes are exchanged over it. By default, the status is
	// set to true.
	AdminEnabled bool `json:"adminEnabled,omitempty"`

	// CircuitInfos: [Output Only] A list of CircuitInfo objects, that
	// describe the individual circuits in this LAG.
	CircuitInfos []*InterconnectCircuitInfo `json:"circuitInfos,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// CustomerName: Customer name, to put in the Letter of Authorization as
	// the party authorized to request a crossconnect.
	CustomerName string `json:"customerName,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// ExpectedOutages: [Output Only] A list of outages expected for this
	// Interconnect.
	ExpectedOutages []*InterconnectOutageNotification `json:"expectedOutages,omitempty"`

	// GoogleIpAddress: [Output Only] IP address configured on the Google
	// side of the Interconnect link. This can be used only for ping tests.
	GoogleIpAddress string `json:"googleIpAddress,omitempty"`

	// GoogleReferenceId: [Output Only] Google reference ID to be used when
	// raising support tickets with Google or otherwise to debug backend
	// connectivity issues.
	GoogleReferenceId string `json:"googleReferenceId,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// InterconnectAttachments: [Output Only] A list of the URLs of all
	// InterconnectAttachments configured to use this Interconnect.
	InterconnectAttachments []string `json:"interconnectAttachments,omitempty"`

	// InterconnectType: Type of interconnect, which can take one of the
	// following values:
	// - PARTNER: A partner-managed interconnection shared between customers
	// though a partner.
	// - DEDICATED: A dedicated physical interconnection with the customer.
	// Note that a value IT_PRIVATE has been deprecated in favor of
	// DEDICATED.
	//
	// Possible values:
	//   "DEDICATED"
	//   "IT_PRIVATE"
	//   "PARTNER"
	InterconnectType string `json:"interconnectType,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#interconnect
	// for interconnects.
	Kind string `json:"kind,omitempty"`

	// LinkType: Type of link requested, which can take one of the following
	// values:
	// - LINK_TYPE_ETHERNET_10G_LR: A 10G Ethernet with LR optics
	// - LINK_TYPE_ETHERNET_100G_LR: A 100G Ethernet with LR optics. Note
	// that this field indicates the speed of each of the links in the
	// bundle, not the speed of the entire bundle.
	//
	// Possible values:
	//   "LINK_TYPE_ETHERNET_100G_LR"
	//   "LINK_TYPE_ETHERNET_10G_LR"
	LinkType string `json:"linkType,omitempty"`

	// Location: URL of the InterconnectLocation object that represents
	// where this connection is to be provisioned.
	Location string `json:"location,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// NocContactEmail: Email address to contact the customer NOC for
	// operations and maintenance notifications regarding this Interconnect.
	// If specified, this will be used for notifications in addition to all
	// other forms described, such as Stackdriver logs alerting and Cloud
	// Notifications.
	NocContactEmail string `json:"nocContactEmail,omitempty"`

	// OperationalStatus: [Output Only] The current status of this
	// Interconnect's functionality, which can take one of the following
	// values:
	// - OS_ACTIVE: A valid Interconnect, which is turned up and is ready to
	// use. Attachments may be provisioned on this Interconnect.
	// - OS_UNPROVISIONED: An Interconnect that has not completed turnup. No
	// attachments may be provisioned on this Interconnect.
	// - OS_UNDER_MAINTENANCE: An Interconnect that is undergoing internal
	// maintenance. No attachments may be provisioned or updated on this
	// Interconnect.
	//
	// Possible values:
	//   "OS_ACTIVE"
	//   "OS_UNPROVISIONED"
	OperationalStatus string `json:"operationalStatus,omitempty"`

	// PeerIpAddress: [Output Only] IP address configured on the customer
	// side of the Interconnect link. The customer should configure this IP
	// address during turnup when prompted by Google NOC. This can be used
	// only for ping tests.
	PeerIpAddress string `json:"peerIpAddress,omitempty"`

	// ProvisionedLinkCount: [Output Only] Number of links actually
	// provisioned in this interconnect.
	ProvisionedLinkCount int64 `json:"provisionedLinkCount,omitempty"`

	// RequestedLinkCount: Target number of physical links in the link
	// bundle, as requested by the customer.
	RequestedLinkCount int64 `json:"requestedLinkCount,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// State: [Output Only] The current state of Interconnect functionality,
	// which can take one of the following values:
	// - ACTIVE: The Interconnect is valid, turned up and ready to use.
	// Attachments may be provisioned on this Interconnect.
	// - UNPROVISIONED: The Interconnect has not completed turnup. No
	// attachments may be provisioned on this Interconnect.
	// - UNDER_MAINTENANCE: The Interconnect is undergoing internal
	// maintenance. No attachments may be provisioned or updated on this
	// Interconnect.
	//
	// Possible values:
	//   "ACTIVE"
	//   "UNPROVISIONED"
	State string `json:"state,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AdminEnabled") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdminEnabled") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Interconnect) MarshalJSON() ([]byte, error) {
	type NoMethod Interconnect
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectAttachment: Represents an Interconnect Attachment (VLAN)
// resource.
//
// You can use Interconnect attachments (VLANS) to connect your Virtual
// Private Cloud networks to your on-premises networks through an
// Interconnect. For more information, read  Creating VLAN Attachments.
// (== resource_for beta.interconnectAttachments ==) (== resource_for
// v1.interconnectAttachments ==)
type InterconnectAttachment struct {
	// AdminEnabled: Determines whether this Attachment will carry packets.
	// Not present for PARTNER_PROVIDER.
	AdminEnabled bool `json:"adminEnabled,omitempty"`

	// Bandwidth: Provisioned bandwidth capacity for the interconnect
	// attachment. For attachments of type DEDICATED, the user can set the
	// bandwidth. For attachments of type PARTNER, the Google Partner that
	// is operating the interconnect must set the bandwidth. Output only for
	// PARTNER type, mutable for PARTNER_PROVIDER and DEDICATED, and can
	// take one of the following values:
	// - BPS_50M: 50 Mbit/s
	// - BPS_100M: 100 Mbit/s
	// - BPS_200M: 200 Mbit/s
	// - BPS_300M: 300 Mbit/s
	// - BPS_400M: 400 Mbit/s
	// - BPS_500M: 500 Mbit/s
	// - BPS_1G: 1 Gbit/s
	// - BPS_2G: 2 Gbit/s
	// - BPS_5G: 5 Gbit/s
	// - BPS_10G: 10 Gbit/s
	// - BPS_20G: 20 Gbit/s
	// - BPS_50G: 50 Gbit/s
	//
	// Possible values:
	//   "BPS_100M"
	//   "BPS_10G"
	//   "BPS_1G"
	//   "BPS_200M"
	//   "BPS_20G"
	//   "BPS_2G"
	//   "BPS_300M"
	//   "BPS_400M"
	//   "BPS_500M"
	//   "BPS_50G"
	//   "BPS_50M"
	//   "BPS_5G"
	Bandwidth string `json:"bandwidth,omitempty"`

	// CandidateSubnets: Up to 16 candidate prefixes that can be used to
	// restrict the allocation of cloudRouterIpAddress and
	// customerRouterIpAddress for this attachment. All prefixes must be
	// within link-local address space (169.254.0.0/16) and must be /29 or
	// shorter (/28, /27, etc). Google will attempt to select an unused /29
	// from the supplied candidate prefix(es). The request will fail if all
	// possible /29s are in use on Google?s edge. If not supplied, Google
	// will randomly select an unused /29 from all of link-local space.
	CandidateSubnets []string `json:"candidateSubnets,omitempty"`

	// CloudRouterIpAddress: [Output Only] IPv4 address + prefix length to
	// be configured on Cloud Router Interface for this interconnect
	// attachment.
	CloudRouterIpAddress string `json:"cloudRouterIpAddress,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// CustomerRouterIpAddress: [Output Only] IPv4 address + prefix length
	// to be configured on the customer router subinterface for this
	// interconnect attachment.
	CustomerRouterIpAddress string `json:"customerRouterIpAddress,omitempty"`

	// Description: An optional description of this resource.
	Description string `json:"description,omitempty"`

	// EdgeAvailabilityDomain: Desired availability domain for the
	// attachment. Only available for type PARTNER, at creation time, and
	// can take one of the following values:
	// - AVAILABILITY_DOMAIN_ANY
	// - AVAILABILITY_DOMAIN_1
	// - AVAILABILITY_DOMAIN_2 For improved reliability, customers should
	// configure a pair of attachments, one per availability domain. The
	// selected availability domain will be provided to the Partner via the
	// pairing key, so that the provisioned circuit will lie in the
	// specified domain. If not specified, the value will default to
	// AVAILABILITY_DOMAIN_ANY.
	//
	// Possible values:
	//   "AVAILABILITY_DOMAIN_1"
	//   "AVAILABILITY_DOMAIN_2"
	//   "AVAILABILITY_DOMAIN_ANY"
	EdgeAvailabilityDomain string `json:"edgeAvailabilityDomain,omitempty"`

	// GoogleReferenceId: [Output Only] Google reference ID, to be used when
	// raising support tickets with Google or otherwise to debug backend
	// connectivity issues. [Deprecated] This field is not used.
	GoogleReferenceId string `json:"googleReferenceId,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Interconnect: URL of the underlying Interconnect object that this
	// attachment's traffic will traverse through.
	Interconnect string `json:"interconnect,omitempty"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#interconnectAttachment for interconnect attachments.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// OperationalStatus: [Output Only] The current status of whether or not
	// this interconnect attachment is functional, which can take one of the
	// following values:
	// - OS_ACTIVE: The attachment has been turned up and is ready to use.
	//
	// - OS_UNPROVISIONED: The attachment is not ready to use yet, because
	// turnup is not complete.
	//
	// Possible values:
	//   "OS_ACTIVE"
	//   "OS_UNPROVISIONED"
	OperationalStatus string `json:"operationalStatus,omitempty"`

	// PairingKey: [Output only for type PARTNER. Input only for
	// PARTNER_PROVIDER. Not present for DEDICATED]. The opaque identifier
	// of an PARTNER attachment used to initiate provisioning with a
	// selected partner. Of the form "XXXXX/region/domain"
	PairingKey string `json:"pairingKey,omitempty"`

	// PartnerAsn: Optional BGP ASN for the router supplied by a Layer 3
	// Partner if they configured BGP on behalf of the customer. Output only
	// for PARTNER type, input only for PARTNER_PROVIDER, not available for
	// DEDICATED.
	PartnerAsn int64 `json:"partnerAsn,omitempty,string"`

	// PartnerMetadata: Informational metadata about Partner attachments
	// from Partners to display to customers. Output only for for PARTNER
	// type, mutable for PARTNER_PROVIDER, not available for DEDICATED.
	PartnerMetadata *InterconnectAttachmentPartnerMetadata `json:"partnerMetadata,omitempty"`

	// PrivateInterconnectInfo: [Output Only] Information specific to an
	// InterconnectAttachment. This property is populated if the
	// interconnect that this is attached to is of type DEDICATED.
	PrivateInterconnectInfo *InterconnectAttachmentPrivateInfo `json:"privateInterconnectInfo,omitempty"`

	// Region: [Output Only] URL of the region where the regional
	// interconnect attachment resides. You must specify this field as part
	// of the HTTP request URL. It is not settable as a field in the request
	// body.
	Region string `json:"region,omitempty"`

	// Router: URL of the Cloud Router to be used for dynamic routing. This
	// router must be in the same region as this InterconnectAttachment. The
	// InterconnectAttachment will automatically connect the Interconnect to
	// the network & region within which the Cloud Router is configured.
	Router string `json:"router,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// State: [Output Only] The current state of this attachment's
	// functionality. Enum values ACTIVE and UNPROVISIONED are shared by
	// DEDICATED/PRIVATE, PARTNER, and PARTNER_PROVIDER interconnect
	// attachments, while enum values PENDING_PARTNER,
	// PARTNER_REQUEST_RECEIVED, and PENDING_CUSTOMER are used for only
	// PARTNER and PARTNER_PROVIDER interconnect attachments. This state can
	// take one of the following values:
	// - ACTIVE: The attachment has been turned up and is ready to use.
	// - UNPROVISIONED: The attachment is not ready to use yet, because
	// turnup is not complete.
	// - PENDING_PARTNER: A newly-created PARTNER attachment that has not
	// yet been configured on the Partner side.
	// - PARTNER_REQUEST_RECEIVED: A PARTNER attachment is in the process of
	// provisioning after a PARTNER_PROVIDER attachment was created that
	// references it.
	// - PENDING_CUSTOMER: A PARTNER or PARTNER_PROVIDER attachment that is
	// waiting for a customer to activate it.
	// - DEFUNCT: The attachment was deleted externally and is no longer
	// functional. This could be because the associated Interconnect was
	// removed, or because the other side of a Partner attachment was
	// deleted.
	//
	// Possible values:
	//   "ACTIVE"
	//   "DEFUNCT"
	//   "PARTNER_REQUEST_RECEIVED"
	//   "PENDING_CUSTOMER"
	//   "PENDING_PARTNER"
	//   "STATE_UNSPECIFIED"
	//   "UNPROVISIONED"
	State string `json:"state,omitempty"`

	// Type: The type of interconnect attachment this is, which can take one
	// of the following values:
	// - DEDICATED: an attachment to a Dedicated Interconnect.
	// - PARTNER: an attachment to a Partner Interconnect, created by the
	// customer.
	// - PARTNER_PROVIDER: an attachment to a Partner Interconnect, created
	// by the partner.
	//
	// Possible values:
	//   "DEDICATED"
	//   "PARTNER"
	//   "PARTNER_PROVIDER"
	Type string `json:"type,omitempty"`

	// VlanTag8021q: The IEEE 802.1Q VLAN tag for this attachment, in the
	// range 2-4094. Only specified at creation time.
	VlanTag8021q int64 `json:"vlanTag8021q,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AdminEnabled") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdminEnabled") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachment) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectAttachmentAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InterconnectAttachmentsScopedList resources.
	Items map[string]InterconnectAttachmentsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#interconnectAttachmentAggregatedList for aggregated lists of
	// interconnect attachments.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InterconnectAttachmentAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectAttachmentAggregatedListWarning: [Output Only]
// Informational warning message.
type InterconnectAttachmentAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InterconnectAttachmentAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectAttachmentAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectAttachmentList: Response to the list request, and
// contains a list of interconnect attachments.
type InterconnectAttachmentList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InterconnectAttachment resources.
	Items []*InterconnectAttachment `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#interconnectAttachmentList for lists of interconnect
	// attachments.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InterconnectAttachmentListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentList) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectAttachmentListWarning: [Output Only] Informational
// warning message.
type InterconnectAttachmentListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InterconnectAttachmentListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectAttachmentListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectAttachmentPartnerMetadata: Informational metadata about
// Partner attachments from Partners to display to customers. These
// fields are propagated from PARTNER_PROVIDER attachments to their
// corresponding PARTNER attachments.
type InterconnectAttachmentPartnerMetadata struct {
	// InterconnectName: Plain text name of the Interconnect this attachment
	// is connected to, as displayed in the Partner?s portal. For instance
	// "Chicago 1". This value may be validated to match approved Partner
	// values.
	InterconnectName string `json:"interconnectName,omitempty"`

	// PartnerName: Plain text name of the Partner providing this
	// attachment. This value may be validated to match approved Partner
	// values.
	PartnerName string `json:"partnerName,omitempty"`

	// PortalUrl: URL of the Partner?s portal for this Attachment. Partners
	// may customise this to be a deep link to the specific resource on the
	// Partner portal. This value may be validated to match approved Partner
	// values.
	PortalUrl string `json:"portalUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InterconnectName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InterconnectName") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentPartnerMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentPartnerMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectAttachmentPrivateInfo: Information for an interconnect
// attachment when this belongs to an interconnect of type DEDICATED.
type InterconnectAttachmentPrivateInfo struct {
	// Tag8021q: [Output Only] 802.1q encapsulation tag to be used for
	// traffic between Google and the customer, going to and from this
	// network and region.
	Tag8021q int64 `json:"tag8021q,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Tag8021q") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Tag8021q") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentPrivateInfo) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentPrivateInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectAttachmentsScopedList struct {
	// InterconnectAttachments: A list of interconnect attachments contained
	// in this scope.
	InterconnectAttachments []*InterconnectAttachment `json:"interconnectAttachments,omitempty"`

	// Warning: Informational warning which replaces the list of addresses
	// when the list is empty.
	Warning *InterconnectAttachmentsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "InterconnectAttachments") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InterconnectAttachments")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectAttachmentsScopedListWarning: Informational warning which
// replaces the list of addresses when the list is empty.
type InterconnectAttachmentsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InterconnectAttachmentsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectAttachmentsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectAttachmentsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectAttachmentsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectCircuitInfo: Describes a single physical circuit between
// the Customer and Google. CircuitInfo objects are created by Google,
// so all fields are output only. Next id: 4
type InterconnectCircuitInfo struct {
	// CustomerDemarcId: Customer-side demarc ID for this circuit.
	CustomerDemarcId string `json:"customerDemarcId,omitempty"`

	// GoogleCircuitId: Google-assigned unique ID for this circuit. Assigned
	// at circuit turn-up.
	GoogleCircuitId string `json:"googleCircuitId,omitempty"`

	// GoogleDemarcId: Google-side demarc ID for this circuit. Assigned at
	// circuit turn-up and provided by Google to the customer in the LOA.
	GoogleDemarcId string `json:"googleDemarcId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CustomerDemarcId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CustomerDemarcId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectCircuitInfo) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectCircuitInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectDiagnostics: Diagnostics information about interconnect,
// contains detailed and current technical information about Google?s
// side of the connection.
type InterconnectDiagnostics struct {
	// ArpCaches: A list of InterconnectDiagnostics.ARPEntry objects,
	// describing individual neighbors currently seen by the Google router
	// in the ARP cache for the Interconnect. This will be empty when the
	// Interconnect is not bundled.
	ArpCaches []*InterconnectDiagnosticsARPEntry `json:"arpCaches,omitempty"`

	// Links: A list of InterconnectDiagnostics.LinkStatus objects,
	// describing the status for each link on the Interconnect.
	Links []*InterconnectDiagnosticsLinkStatus `json:"links,omitempty"`

	// MacAddress: The MAC address of the Interconnect's bundle interface.
	MacAddress string `json:"macAddress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArpCaches") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ArpCaches") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectDiagnostics) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectDiagnostics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectDiagnosticsARPEntry: Describing the ARP neighbor entries
// seen on this link
type InterconnectDiagnosticsARPEntry struct {
	// IpAddress: The IP address of this ARP neighbor.
	IpAddress string `json:"ipAddress,omitempty"`

	// MacAddress: The MAC address of this ARP neighbor.
	MacAddress string `json:"macAddress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpAddress") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpAddress") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectDiagnosticsARPEntry) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectDiagnosticsARPEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectDiagnosticsLinkLACPStatus struct {
	// GoogleSystemId: System ID of the port on Google?s side of the LACP
	// exchange.
	GoogleSystemId string `json:"googleSystemId,omitempty"`

	// NeighborSystemId: System ID of the port on the neighbor?s side of the
	// LACP exchange.
	NeighborSystemId string `json:"neighborSystemId,omitempty"`

	// State: The state of a LACP link, which can take one of the following
	// values:
	// - ACTIVE: The link is configured and active within the bundle.
	// - DETACHED: The link is not configured within the bundle. This means
	// that the rest of the object should be empty.
	//
	// Possible values:
	//   "ACTIVE"
	//   "DETACHED"
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GoogleSystemId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GoogleSystemId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectDiagnosticsLinkLACPStatus) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectDiagnosticsLinkLACPStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectDiagnosticsLinkOpticalPower struct {
	// State: The status of the current value when compared to the warning
	// and alarm levels for the receiving or transmitting transceiver.
	// Possible states include:
	// - OK: The value has not crossed a warning threshold.
	// - LOW_WARNING: The value has crossed below the low warning threshold.
	//
	// - HIGH_WARNING: The value has crossed above the high warning
	// threshold.
	// - LOW_ALARM: The value has crossed below the low alarm threshold.
	// - HIGH_ALARM: The value has crossed above the high alarm threshold.
	//
	// Possible values:
	//   "HIGH_ALARM"
	//   "HIGH_WARNING"
	//   "LOW_ALARM"
	//   "LOW_WARNING"
	//   "OK"
	State string `json:"state,omitempty"`

	// Value: Value of the current receiving or transmitting optical power,
	// read in dBm. Take a known good optical value, give it a 10% margin
	// and trigger warnings relative to that value. In general, a -7dBm
	// warning and a -11dBm alarm are good optical value estimates for most
	// links.
	Value float64 `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "State") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "State") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectDiagnosticsLinkOpticalPower) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectDiagnosticsLinkOpticalPower
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *InterconnectDiagnosticsLinkOpticalPower) UnmarshalJSON(data []byte) error {
	type NoMethod InterconnectDiagnosticsLinkOpticalPower
	var s1 struct {
		Value gensupport.JSONFloat64 `json:"value"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Value = float64(s1.Value)
	return nil
}

type InterconnectDiagnosticsLinkStatus struct {
	// ArpCaches: A list of InterconnectDiagnostics.ARPEntry objects,
	// describing the ARP neighbor entries seen on this link. This will be
	// empty if the link is bundled
	ArpCaches []*InterconnectDiagnosticsARPEntry `json:"arpCaches,omitempty"`

	// CircuitId: The unique ID for this link assigned during turn up by
	// Google.
	CircuitId string `json:"circuitId,omitempty"`

	// GoogleDemarc: The Demarc address assigned by Google and provided in
	// the LoA.
	GoogleDemarc string `json:"googleDemarc,omitempty"`

	LacpStatus *InterconnectDiagnosticsLinkLACPStatus `json:"lacpStatus,omitempty"`

	// ReceivingOpticalPower: An InterconnectDiagnostics.LinkOpticalPower
	// object, describing the current value and status of the received light
	// level.
	ReceivingOpticalPower *InterconnectDiagnosticsLinkOpticalPower `json:"receivingOpticalPower,omitempty"`

	// TransmittingOpticalPower: An InterconnectDiagnostics.LinkOpticalPower
	// object, describing the current value and status of the transmitted
	// light level.
	TransmittingOpticalPower *InterconnectDiagnosticsLinkOpticalPower `json:"transmittingOpticalPower,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArpCaches") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ArpCaches") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectDiagnosticsLinkStatus) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectDiagnosticsLinkStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectList: Response to the list request, and contains a list
// of interconnects.
type InterconnectList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Interconnect resources.
	Items []*Interconnect `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#interconnectList
	// for lists of interconnects.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InterconnectListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectList) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectListWarning: [Output Only] Informational warning message.
type InterconnectListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InterconnectListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectLocation: Represents an Interconnect Attachment (VLAN)
// Location resource.
//
// You can use this resource to find location details about an
// Interconnect attachment (VLAN). For more information about
// interconnect attachments, read  Creating VLAN Attachments.
type InterconnectLocation struct {
	// Address: [Output Only] The postal address of the Point of Presence,
	// each line in the address is separated by a newline character.
	Address string `json:"address,omitempty"`

	// AvailabilityZone: [Output Only] Availability zone for this
	// InterconnectLocation. Within a metropolitan area (metro), maintenance
	// will not be simultaneously scheduled in more than one availability
	// zone. Example: "zone1" or "zone2".
	AvailabilityZone string `json:"availabilityZone,omitempty"`

	// City: [Output Only] Metropolitan area designator that indicates which
	// city an interconnect is located. For example: "Chicago, IL",
	// "Amsterdam, Netherlands".
	City string `json:"city,omitempty"`

	// Continent: [Output Only] Continent for this location, which can take
	// one of the following values:
	// - AFRICA
	// - ASIA_PAC
	// - EUROPE
	// - NORTH_AMERICA
	// - SOUTH_AMERICA
	//
	// Possible values:
	//   "AFRICA"
	//   "ASIA_PAC"
	//   "C_AFRICA"
	//   "C_ASIA_PAC"
	//   "C_EUROPE"
	//   "C_NORTH_AMERICA"
	//   "C_SOUTH_AMERICA"
	//   "EUROPE"
	//   "NORTH_AMERICA"
	//   "SOUTH_AMERICA"
	Continent string `json:"continent,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: [Output Only] An optional description of the resource.
	Description string `json:"description,omitempty"`

	// FacilityProvider: [Output Only] The name of the provider for this
	// facility (e.g., EQUINIX).
	FacilityProvider string `json:"facilityProvider,omitempty"`

	// FacilityProviderFacilityId: [Output Only] A provider-assigned
	// Identifier for this facility (e.g., Ashburn-DC1).
	FacilityProviderFacilityId string `json:"facilityProviderFacilityId,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#interconnectLocation for interconnect locations.
	Kind string `json:"kind,omitempty"`

	// Name: [Output Only] Name of the resource.
	Name string `json:"name,omitempty"`

	// PeeringdbFacilityId: [Output Only] The peeringdb identifier for this
	// facility (corresponding with a netfac type in peeringdb).
	PeeringdbFacilityId string `json:"peeringdbFacilityId,omitempty"`

	// RegionInfos: [Output Only] A list of InterconnectLocation.RegionInfo
	// objects, that describe parameters pertaining to the relation between
	// this InterconnectLocation and various Google Cloud regions.
	RegionInfos []*InterconnectLocationRegionInfo `json:"regionInfos,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Status: [Output Only] The status of this InterconnectLocation, which
	// can take one of the following values:
	// - CLOSED: The InterconnectLocation is closed and is unavailable for
	// provisioning new Interconnects.
	// - AVAILABLE: The InterconnectLocation is available for provisioning
	// new Interconnects.
	//
	// Possible values:
	//   "AVAILABLE"
	//   "CLOSED"
	Status string `json:"status,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Address") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Address") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectLocation) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectLocation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectLocationList: Response to the list request, and contains
// a list of interconnect locations.
type InterconnectLocationList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InterconnectLocation resources.
	Items []*InterconnectLocation `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#interconnectLocationList for lists of interconnect locations.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *InterconnectLocationListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectLocationList) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectLocationList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectLocationListWarning: [Output Only] Informational warning
// message.
type InterconnectLocationListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*InterconnectLocationListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectLocationListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectLocationListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type InterconnectLocationListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectLocationListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectLocationListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectLocationRegionInfo: Information about any potential
// InterconnectAttachments between an Interconnect at a specific
// InterconnectLocation, and a specific Cloud Region.
type InterconnectLocationRegionInfo struct {
	// ExpectedRttMs: Expected round-trip time in milliseconds, from this
	// InterconnectLocation to a VM in this region.
	ExpectedRttMs int64 `json:"expectedRttMs,omitempty,string"`

	// LocationPresence: Identifies the network presence of this location.
	//
	// Possible values:
	//   "GLOBAL"
	//   "LOCAL_REGION"
	//   "LP_GLOBAL"
	//   "LP_LOCAL_REGION"
	LocationPresence string `json:"locationPresence,omitempty"`

	// Region: URL for the region of this location.
	Region string `json:"region,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExpectedRttMs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExpectedRttMs") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectLocationRegionInfo) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectLocationRegionInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectOutageNotification: Description of a planned outage on
// this Interconnect. Next id: 9
type InterconnectOutageNotification struct {
	// AffectedCircuits: If issue_type is IT_PARTIAL_OUTAGE, a list of the
	// Google-side circuit IDs that will be affected.
	AffectedCircuits []string `json:"affectedCircuits,omitempty"`

	// Description: A description about the purpose of the outage.
	Description string `json:"description,omitempty"`

	// EndTime: Scheduled end time for the outage (milliseconds since Unix
	// epoch).
	EndTime int64 `json:"endTime,omitempty,string"`

	// IssueType: Form this outage is expected to take, which can take one
	// of the following values:
	// - OUTAGE: The Interconnect may be completely out of service for some
	// or all of the specified window.
	// - PARTIAL_OUTAGE: Some circuits comprising the Interconnect as a
	// whole should remain up, but with reduced bandwidth. Note that the
	// versions of this enum prefixed with "IT_" have been deprecated in
	// favor of the unprefixed values.
	//
	// Possible values:
	//   "IT_OUTAGE"
	//   "IT_PARTIAL_OUTAGE"
	//   "OUTAGE"
	//   "PARTIAL_OUTAGE"
	IssueType string `json:"issueType,omitempty"`

	// Name: Unique identifier for this outage notification.
	Name string `json:"name,omitempty"`

	// Source: The party that generated this notification, which can take
	// the following value:
	// - GOOGLE: this notification as generated by Google. Note that the
	// value of NSRC_GOOGLE has been deprecated in favor of GOOGLE.
	//
	// Possible values:
	//   "GOOGLE"
	//   "NSRC_GOOGLE"
	Source string `json:"source,omitempty"`

	// StartTime: Scheduled start time for the outage (milliseconds since
	// Unix epoch).
	StartTime int64 `json:"startTime,omitempty,string"`

	// State: State of this notification, which can take one of the
	// following values:
	// - ACTIVE: This outage notification is active. The event could be in
	// the past, present, or future. See start_time and end_time for
	// scheduling.
	// - CANCELLED: The outage associated with this notification was
	// cancelled before the outage was due to start. Note that the versions
	// of this enum prefixed with "NS_" have been deprecated in favor of the
	// unprefixed values.
	//
	// Possible values:
	//   "ACTIVE"
	//   "CANCELLED"
	//   "COMPLETED"
	//   "NS_ACTIVE"
	//   "NS_CANCELED"
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AffectedCircuits") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AffectedCircuits") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectOutageNotification) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectOutageNotification
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InterconnectsGetDiagnosticsResponse: Response for the
// InterconnectsGetDiagnosticsRequest.
type InterconnectsGetDiagnosticsResponse struct {
	Result *InterconnectDiagnostics `json:"result,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Result") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Result") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InterconnectsGetDiagnosticsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod InterconnectsGetDiagnosticsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// License: A license resource.
type License struct {
	// ChargesUseFee: [Output Only] Deprecated. This field no longer
	// reflects whether a license charges a usage fee.
	ChargesUseFee bool `json:"chargesUseFee,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional textual description of the resource;
	// provided by the client when the resource is created.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of resource. Always compute#license for
	// licenses.
	Kind string `json:"kind,omitempty"`

	// LicenseCode: [Output Only] The unique code used to attach this
	// license to images, snapshots, and disks.
	LicenseCode uint64 `json:"licenseCode,omitempty,string"`

	// Name: Name of the resource. The name must be 1-63 characters long and
	// comply with RFC1035.
	Name string `json:"name,omitempty"`

	ResourceRequirements *LicenseResourceRequirements `json:"resourceRequirements,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Transferable: If false, licenses will not be copied from the source
	// resource when creating an image from a disk, disk from snapshot, or
	// snapshot from disk.
	Transferable bool `json:"transferable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ChargesUseFee") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChargesUseFee") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *License) MarshalJSON() ([]byte, error) {
	type NoMethod License
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type LicenseCode struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: [Output Only] Description of this License Code.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of resource. Always compute#licenseCode for
	// licenses.
	Kind string `json:"kind,omitempty"`

	// LicenseAlias: [Output Only] URL and description aliases of Licenses
	// with the same License Code.
	LicenseAlias []*LicenseCodeLicenseAlias `json:"licenseAlias,omitempty"`

	// Name: [Output Only] Name of the resource. The name is 1-20 characters
	// long and must be a valid 64 bit integer.
	Name string `json:"name,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// State: [Output Only] Current state of this License Code.
	//
	// Possible values:
	//   "DISABLED"
	//   "ENABLED"
	//   "RESTRICTED"
	//   "STATE_UNSPECIFIED"
	//   "TERMINATED"
	State string `json:"state,omitempty"`

	// Transferable: [Output Only] If true, the license will remain attached
	// when creating images or snapshots from disks. Otherwise, the license
	// is not transferred.
	Transferable bool `json:"transferable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *LicenseCode) MarshalJSON() ([]byte, error) {
	type NoMethod LicenseCode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type LicenseCodeLicenseAlias struct {
	// Description: [Output Only] Description of this License Code.
	Description string `json:"description,omitempty"`

	// SelfLink: [Output Only] URL of license corresponding to this License
	// Code.
	SelfLink string `json:"selfLink,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LicenseCodeLicenseAlias) MarshalJSON() ([]byte, error) {
	type NoMethod LicenseCodeLicenseAlias
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type LicenseResourceRequirements struct {
	// MinGuestCpuCount: Minimum number of guest cpus required to use the
	// Instance. Enforced at Instance creation and Instance start.
	MinGuestCpuCount int64 `json:"minGuestCpuCount,omitempty"`

	// MinMemoryMb: Minimum memory required to use the Instance. Enforced at
	// Instance creation and Instance start.
	MinMemoryMb int64 `json:"minMemoryMb,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MinGuestCpuCount") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MinGuestCpuCount") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *LicenseResourceRequirements) MarshalJSON() ([]byte, error) {
	type NoMethod LicenseResourceRequirements
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type LicensesListResponse struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of License resources.
	Items []*License `json:"items,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *LicensesListResponseWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LicensesListResponse) MarshalJSON() ([]byte, error) {
	type NoMethod LicensesListResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LicensesListResponseWarning: [Output Only] Informational warning
// message.
type LicensesListResponseWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*LicensesListResponseWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LicensesListResponseWarning) MarshalJSON() ([]byte, error) {
	type NoMethod LicensesListResponseWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type LicensesListResponseWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LicensesListResponseWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod LicensesListResponseWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LogConfig: Specifies what kind of log the caller must write
type LogConfig struct {
	// CloudAudit: Cloud audit options.
	CloudAudit *LogConfigCloudAuditOptions `json:"cloudAudit,omitempty"`

	// Counter: Counter options.
	Counter *LogConfigCounterOptions `json:"counter,omitempty"`

	// DataAccess: Data access options.
	DataAccess *LogConfigDataAccessOptions `json:"dataAccess,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CloudAudit") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CloudAudit") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LogConfig) MarshalJSON() ([]byte, error) {
	type NoMethod LogConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LogConfigCloudAuditOptions: Write a Cloud Audit log
type LogConfigCloudAuditOptions struct {
	// AuthorizationLoggingOptions: Information used by the Cloud Audit
	// Logging pipeline.
	AuthorizationLoggingOptions *AuthorizationLoggingOptions `json:"authorizationLoggingOptions,omitempty"`

	// LogName: The log_name to populate in the Cloud Audit Record.
	//
	// Possible values:
	//   "ADMIN_ACTIVITY"
	//   "DATA_ACCESS"
	//   "UNSPECIFIED_LOG_NAME"
	LogName string `json:"logName,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AuthorizationLoggingOptions") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "AuthorizationLoggingOptions") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LogConfigCloudAuditOptions) MarshalJSON() ([]byte, error) {
	type NoMethod LogConfigCloudAuditOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LogConfigCounterOptions: Increment a streamz counter with the
// specified metric and field names.
//
// Metric names should start with a '/', generally be lowercase-only,
// and end in "_count". Field names should not contain an initial slash.
// The actual exported metric names will have "/iam/policy"
// prepended.
//
// Field names correspond to IAM request parameters and field values are
// their respective values.
//
// Supported field names: - "authority", which is "[token]" if
// IAMContext.token is present, otherwise the value of
// IAMContext.authority_selector if present, and otherwise a
// representation of IAMContext.principal; or - "iam_principal", a
// representation of IAMContext.principal even if a token or authority
// selector is present; or - "" (empty string), resulting in a counter
// with no fields.
//
// Examples: counter { metric: "/debug_access_count" field:
// "iam_principal" } ==> increment counter
// /iam/policy/debug_access_count {iam_principal=[value of
// IAMContext.principal]}
//
// TODO(b/141846426): Consider supporting "authority" and
// "iam_principal" fields in the same counter.
type LogConfigCounterOptions struct {
	// CustomFields: Custom fields.
	CustomFields []*LogConfigCounterOptionsCustomField `json:"customFields,omitempty"`

	// Field: The field value to attribute.
	Field string `json:"field,omitempty"`

	// Metric: The metric to update.
	Metric string `json:"metric,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CustomFields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CustomFields") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LogConfigCounterOptions) MarshalJSON() ([]byte, error) {
	type NoMethod LogConfigCounterOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LogConfigCounterOptionsCustomField: Custom fields. These can be used
// to create a counter with arbitrary field/value pairs. See:
// go/rpcsp-custom-fields.
type LogConfigCounterOptionsCustomField struct {
	// Name: Name is the field name.
	Name string `json:"name,omitempty"`

	// Value: Value is the field value. It is important that in contrast to
	// the CounterOptions.field, the value here is a constant that is not
	// derived from the IAMContext.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LogConfigCounterOptionsCustomField) MarshalJSON() ([]byte, error) {
	type NoMethod LogConfigCounterOptionsCustomField
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LogConfigDataAccessOptions: Write a Data Access (Gin) log
type LogConfigDataAccessOptions struct {
	// LogMode: Whether Gin logging should happen in a fail-closed manner at
	// the caller. This is relevant only in the LocalIAM implementation, for
	// now.
	//
	// Possible values:
	//   "LOG_FAIL_CLOSED"
	//   "LOG_MODE_UNSPECIFIED"
	LogMode string `json:"logMode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LogMode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LogMode") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LogConfigDataAccessOptions) MarshalJSON() ([]byte, error) {
	type NoMethod LogConfigDataAccessOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MachineType: Represents a Machine Type resource.
//
// You can use specific machine types for your VM instances based on
// performance and pricing requirements. For more information, read
// Machine Types. (== resource_for v1.machineTypes ==) (== resource_for
// beta.machineTypes ==)
type MachineType struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Deprecated: [Output Only] The deprecation status associated with this
	// machine type.
	Deprecated *DeprecationStatus `json:"deprecated,omitempty"`

	// Description: [Output Only] An optional textual description of the
	// resource.
	Description string `json:"description,omitempty"`

	// GuestCpus: [Output Only] The number of virtual CPUs that are
	// available to the instance.
	GuestCpus int64 `json:"guestCpus,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// ImageSpaceGb: [Deprecated] This property is deprecated and will never
	// be populated with any relevant values.
	ImageSpaceGb int64 `json:"imageSpaceGb,omitempty"`

	// IsSharedCpu: [Output Only] Whether this machine type has a shared
	// CPU. See Shared-core machine types for more information.
	IsSharedCpu bool `json:"isSharedCpu,omitempty"`

	// Kind: [Output Only] The type of the resource. Always
	// compute#machineType for machine types.
	Kind string `json:"kind,omitempty"`

	// MaximumPersistentDisks: [Output Only] Maximum persistent disks
	// allowed.
	MaximumPersistentDisks int64 `json:"maximumPersistentDisks,omitempty"`

	// MaximumPersistentDisksSizeGb: [Output Only] Maximum total persistent
	// disks size (GB) allowed.
	MaximumPersistentDisksSizeGb int64 `json:"maximumPersistentDisksSizeGb,omitempty,string"`

	// MemoryMb: [Output Only] The amount of physical memory available to
	// the instance, defined in MB.
	MemoryMb int64 `json:"memoryMb,omitempty"`

	// Name: [Output Only] Name of the resource.
	Name string `json:"name,omitempty"`

	// ScratchDisks: [Output Only] A list of extended scratch disks assigned
	// to the instance.
	ScratchDisks []*MachineTypeScratchDisks `json:"scratchDisks,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Zone: [Output Only] The name of the zone where the machine type
	// resides, such as us-central1-a.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *MachineType) MarshalJSON() ([]byte, error) {
	type NoMethod MachineType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MachineTypeScratchDisks struct {
	// DiskGb: Size of the scratch disk, defined in GB.
	DiskGb int64 `json:"diskGb,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DiskGb") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DiskGb") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypeScratchDisks) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypeScratchDisks
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MachineTypeAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of MachineTypesScopedList resources.
	Items map[string]MachineTypesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#machineTypeAggregatedList for aggregated lists of machine
	// types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *MachineTypeAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypeAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypeAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MachineTypeAggregatedListWarning: [Output Only] Informational warning
// message.
type MachineTypeAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*MachineTypeAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypeAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypeAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MachineTypeAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypeAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypeAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MachineTypeList: Contains a list of machine types.
type MachineTypeList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of MachineType resources.
	Items []*MachineType `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#machineTypeList
	// for lists of machine types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *MachineTypeListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypeList) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypeList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MachineTypeListWarning: [Output Only] Informational warning message.
type MachineTypeListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*MachineTypeListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypeListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypeListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MachineTypeListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypeListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypeListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MachineTypesScopedList struct {
	// MachineTypes: [Output Only] A list of machine types contained in this
	// scope.
	MachineTypes []*MachineType `json:"machineTypes,omitempty"`

	// Warning: [Output Only] An informational warning that appears when the
	// machine types list is empty.
	Warning *MachineTypesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MachineTypes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MachineTypes") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MachineTypesScopedListWarning: [Output Only] An informational warning
// that appears when the machine types list is empty.
type MachineTypesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*MachineTypesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MachineTypesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MachineTypesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod MachineTypesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ManagedInstance: A Managed Instance resource.
type ManagedInstance struct {
	// CurrentAction: [Output Only] The current action that the managed
	// instance group has scheduled for the instance. Possible values:
	// - NONE The instance is running, and the managed instance group does
	// not have any scheduled actions for this instance.
	// - CREATING The managed instance group is creating this instance. If
	// the group fails to create this instance, it will try again until it
	// is successful.
	// - CREATING_WITHOUT_RETRIES The managed instance group is attempting
	// to create this instance only once. If the group fails to create this
	// instance, it does not try again and the group's targetSize value is
	// decreased instead.
	// - RECREATING The managed instance group is recreating this instance.
	//
	// - DELETING The managed instance group is permanently deleting this
	// instance.
	// - ABANDONING The managed instance group is abandoning this instance.
	// The instance will be removed from the instance group and from any
	// target pools that are associated with this group.
	// - RESTARTING The managed instance group is restarting the instance.
	//
	// - REFRESHING The managed instance group is applying configuration
	// changes to the instance without stopping it. For example, the group
	// can update the target pool list for an instance without stopping that
	// instance.
	// - VERIFYING The managed instance group has created the instance and
	// it is in the process of being verified.
	//
	// Possible values:
	//   "ABANDONING"
	//   "CREATING"
	//   "CREATING_WITHOUT_RETRIES"
	//   "DELETING"
	//   "NONE"
	//   "RECREATING"
	//   "REFRESHING"
	//   "RESTARTING"
	//   "VERIFYING"
	CurrentAction string `json:"currentAction,omitempty"`

	// Id: [Output only] The unique identifier for this resource. This field
	// is empty when instance does not exist.
	Id uint64 `json:"id,omitempty,string"`

	// Instance: [Output Only] The URL of the instance. The URL can exist
	// even if the instance has not yet been created.
	Instance string `json:"instance,omitempty"`

	// InstanceStatus: [Output Only] The status of the instance. This field
	// is empty when the instance does not exist.
	//
	// Possible values:
	//   "PROVISIONING"
	//   "REPAIRING"
	//   "RUNNING"
	//   "STAGING"
	//   "STOPPED"
	//   "STOPPING"
	//   "SUSPENDED"
	//   "SUSPENDING"
	//   "TERMINATED"
	InstanceStatus string `json:"instanceStatus,omitempty"`

	// LastAttempt: [Output Only] Information about the last attempt to
	// create or delete the instance.
	LastAttempt *ManagedInstanceLastAttempt `json:"lastAttempt,omitempty"`

	// Version: [Output Only] Intended version of this instance.
	Version *ManagedInstanceVersion `json:"version,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CurrentAction") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CurrentAction") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ManagedInstance) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedInstance
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ManagedInstanceLastAttempt struct {
	// Errors: [Output Only] Encountered errors during the last attempt to
	// create or delete the instance.
	Errors *ManagedInstanceLastAttemptErrors `json:"errors,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Errors") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Errors") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ManagedInstanceLastAttempt) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedInstanceLastAttempt
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ManagedInstanceLastAttemptErrors: [Output Only] Encountered errors
// during the last attempt to create or delete the instance.
type ManagedInstanceLastAttemptErrors struct {
	// Errors: [Output Only] The array of errors encountered while
	// processing this operation.
	Errors []*ManagedInstanceLastAttemptErrorsErrors `json:"errors,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Errors") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Errors") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ManagedInstanceLastAttemptErrors) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedInstanceLastAttemptErrors
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ManagedInstanceLastAttemptErrorsErrors struct {
	// Code: [Output Only] The error type identifier for this error.
	Code string `json:"code,omitempty"`

	// Location: [Output Only] Indicates the field in the request that
	// caused the error. This property is optional.
	Location string `json:"location,omitempty"`

	// Message: [Output Only] An optional, human-readable error message.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ManagedInstanceLastAttemptErrorsErrors) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedInstanceLastAttemptErrorsErrors
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ManagedInstanceVersion struct {
	// InstanceTemplate: [Output Only] The intended template of the
	// instance. This field is empty when current_action is one of {
	// DELETING, ABANDONING }.
	InstanceTemplate string `json:"instanceTemplate,omitempty"`

	// Name: [Output Only] Name of the version.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceTemplate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceTemplate") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ManagedInstanceVersion) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedInstanceVersion
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Metadata: A metadata key/value entry.
type Metadata struct {
	// Fingerprint: Specifies a fingerprint for this request, which is
	// essentially a hash of the metadata's contents and used for optimistic
	// locking. The fingerprint is initially generated by Compute Engine and
	// changes after every request to modify or update metadata. You must
	// always provide an up-to-date fingerprint hash in order to update or
	// change metadata, otherwise the request will fail with error 412
	// conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve the
	// resource.
	Fingerprint string `json:"fingerprint,omitempty"`

	// Items: Array of key/value pairs. The total size of all keys and
	// values must be less than 512 KB.
	Items []*MetadataItems `json:"items,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#metadata for
	// metadata.
	Kind string `json:"kind,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fingerprint") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Metadata) MarshalJSON() ([]byte, error) {
	type NoMethod Metadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MetadataItems struct {
	// Key: Key for the metadata entry. Keys must conform to the following
	// regexp: [a-zA-Z0-9-_]+, and be less than 128 bytes in length. This is
	// reflected as part of a URL in the metadata server. Additionally, to
	// avoid ambiguity, keys must not conflict with any other metadata keys
	// for the project.
	Key string `json:"key,omitempty"`

	// Value: Value for the metadata entry. These are free-form strings, and
	// only have meaning as interpreted by the image running in the
	// instance. The only restriction placed on values is that their size
	// must be less than or equal to 262144 bytes (256 KiB).
	Value *string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MetadataItems) MarshalJSON() ([]byte, error) {
	type NoMethod MetadataItems
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MetadataFilter: Opaque filter criteria used by loadbalancers to
// restrict routing configuration to a limited set of loadbalancing
// proxies. Proxies and sidecars involved in loadbalancing would
// typically present metadata to the loadbalancers which need to match
// criteria specified here. If a match takes place, the relevant routing
// configuration is made available to those proxies.
// For each metadataFilter in this list, if its filterMatchCriteria is
// set to MATCH_ANY, at least one of the filterLabels must match the
// corresponding label provided in the metadata. If its
// filterMatchCriteria is set to MATCH_ALL, then all of its filterLabels
// must match with corresponding labels in the provided metadata.
// An example for using metadataFilters would be: if loadbalancing
// involves  Envoys, they will only receive routing configuration when
// values in metadataFilters match values supplied in <a
// href="https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/core/b
// ase.proto#envoy-api-msg-core-node" Node metadata of their XDS
// requests to loadbalancers.
type MetadataFilter struct {
	// FilterLabels: The list of label value pairs that must match labels in
	// the provided metadata based on filterMatchCriteria
	// This list must not be empty and can have at the most 64 entries.
	FilterLabels []*MetadataFilterLabelMatch `json:"filterLabels,omitempty"`

	// FilterMatchCriteria: Specifies how individual filterLabel matches
	// within the list of filterLabels contribute towards the overall
	// metadataFilter match.
	// Supported values are:
	// - MATCH_ANY: At least one of the filterLabels must have a matching
	// label in the provided metadata.
	// - MATCH_ALL: All filterLabels must have matching labels in the
	// provided metadata.
	//
	// Possible values:
	//   "MATCH_ALL"
	//   "MATCH_ANY"
	//   "NOT_SET"
	FilterMatchCriteria string `json:"filterMatchCriteria,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FilterLabels") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "FilterLabels") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MetadataFilter) MarshalJSON() ([]byte, error) {
	type NoMethod MetadataFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MetadataFilterLabelMatch: MetadataFilter label name value pairs that
// are expected to match corresponding labels presented as metadata to
// the loadbalancer.
type MetadataFilterLabelMatch struct {
	// Name: Name of metadata label.
	// The name can have a maximum length of 1024 characters and must be at
	// least 1 character long.
	Name string `json:"name,omitempty"`

	// Value: The value of the label must match the specified value.
	// value can have a maximum length of 1024 characters.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MetadataFilterLabelMatch) MarshalJSON() ([]byte, error) {
	type NoMethod MetadataFilterLabelMatch
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NamedPort: The named port. For example: .
type NamedPort struct {
	// Name: The name for this named port. The name must be 1-63 characters
	// long, and comply with RFC1035.
	Name string `json:"name,omitempty"`

	// Port: The port number, which can be a value between 1 and 65535.
	Port int64 `json:"port,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NamedPort) MarshalJSON() ([]byte, error) {
	type NoMethod NamedPort
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Network: Represents a VPC Network resource.
//
// Networks connect resources to each other and to the internet. For
// more information, read Virtual Private Cloud (VPC) Network. (==
// resource_for v1.networks ==) (== resource_for beta.networks ==)
type Network struct {
	// IPv4Range: Deprecated in favor of subnet mode networks. The range of
	// internal addresses that are legal on this network. This range is a
	// CIDR specification, for example: 192.168.0.0/16. Provided by the
	// client when the network is created.
	IPv4Range string `json:"IPv4Range,omitempty"`

	// AutoCreateSubnetworks: When set to true, the VPC network is created
	// in "auto" mode. When set to false, the VPC network is created in
	// "custom" mode.
	//
	// An auto mode VPC network starts with one subnet per region. Each
	// subnet has a predetermined range as described in Auto mode VPC
	// network IP ranges.
	AutoCreateSubnetworks bool `json:"autoCreateSubnetworks,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// field when you create the resource.
	Description string `json:"description,omitempty"`

	// GatewayIPv4: [Output Only] The gateway address for default routing
	// out of the network, selected by GCP.
	GatewayIPv4 string `json:"gatewayIPv4,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#network for
	// networks.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?. The first
	// character must be a lowercase letter, and all following characters
	// (except for the last character) must be a dash, lowercase letter, or
	// digit. The last character must be a lowercase letter or digit.
	Name string `json:"name,omitempty"`

	// Peerings: [Output Only] A list of network peerings for the resource.
	Peerings []*NetworkPeering `json:"peerings,omitempty"`

	// RoutingConfig: The network-level routing configuration for this
	// network. Used by Cloud Router to determine what type of network-wide
	// routing behavior to enforce.
	RoutingConfig *NetworkRoutingConfig `json:"routingConfig,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Subnetworks: [Output Only] Server-defined fully-qualified URLs for
	// all subnetworks in this VPC network.
	Subnetworks []string `json:"subnetworks,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "IPv4Range") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IPv4Range") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Network) MarshalJSON() ([]byte, error) {
	type NoMethod Network
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkEndpoint: The network endpoint.
type NetworkEndpoint struct {
	// Instance: The name for a specific VM instance that the IP address
	// belongs to. This is required for network endpoints of type
	// GCE_VM_IP_PORT. The instance must be in the same zone of network
	// endpoint group.
	//
	// The name must be 1-63 characters long, and comply with RFC1035.
	Instance string `json:"instance,omitempty"`

	// IpAddress: Optional IPv4 address of network endpoint. The IP address
	// must belong to a VM in Compute Engine (either the primary IP or as
	// part of an aliased IP range). If the IP address is not specified,
	// then the primary IP address for the VM instance in the network that
	// the network endpoint group belongs to will be used.
	IpAddress string `json:"ipAddress,omitempty"`

	// Port: Optional port number of network endpoint. If not specified and
	// the NetworkEndpointGroup.network_endpoint_type is GCE_IP_PORT, the
	// defaultPort for the network endpoint group will be used.
	Port int64 `json:"port,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instance") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instance") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpoint) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpoint
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkEndpointGroup: Represents a collection of network
// endpoints.
//
// For more information read Setting up network endpoint groups in load
// balancing. (== resource_for v1.networkEndpointGroups ==) (==
// resource_for beta.networkEndpointGroups ==)
type NetworkEndpointGroup struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// DefaultPort: The default port used if the port number is not
	// specified in the network endpoint.
	DefaultPort int64 `json:"defaultPort,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#networkEndpointGroup for network endpoint group.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource; provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Network: The URL of the network to which all network endpoints in the
	// NEG belong. Uses "default" project network if unspecified.
	Network string `json:"network,omitempty"`

	// NetworkEndpointType: Type of network endpoints in this network
	// endpoint group. Currently the only supported value is GCE_VM_IP_PORT.
	//
	// Possible values:
	//   "GCE_VM_IP_PORT"
	NetworkEndpointType string `json:"networkEndpointType,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Size: [Output only] Number of network endpoints in the network
	// endpoint group.
	Size int64 `json:"size,omitempty"`

	// Subnetwork: Optional URL of the subnetwork to which all network
	// endpoints in the NEG belong.
	Subnetwork string `json:"subnetwork,omitempty"`

	// Zone: [Output Only] The URL of the zone where the network endpoint
	// group is located.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroup) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NetworkEndpointGroupsScopedList resources.
	Items map[string]NetworkEndpointGroupsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#networkEndpointGroupAggregatedList for aggregated lists of
	// network endpoint groups.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NetworkEndpointGroupAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkEndpointGroupAggregatedListWarning: [Output Only]
// Informational warning message.
type NetworkEndpointGroupAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NetworkEndpointGroupAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NetworkEndpointGroup resources.
	Items []*NetworkEndpointGroup `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#networkEndpointGroupList for network endpoint group lists.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NetworkEndpointGroupListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupList) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkEndpointGroupListWarning: [Output Only] Informational warning
// message.
type NetworkEndpointGroupListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NetworkEndpointGroupListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupsAttachEndpointsRequest struct {
	// NetworkEndpoints: The list of network endpoints to be attached.
	NetworkEndpoints []*NetworkEndpoint `json:"networkEndpoints,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NetworkEndpoints") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NetworkEndpoints") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsAttachEndpointsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsAttachEndpointsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupsDetachEndpointsRequest struct {
	// NetworkEndpoints: The list of network endpoints to be detached.
	NetworkEndpoints []*NetworkEndpoint `json:"networkEndpoints,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NetworkEndpoints") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NetworkEndpoints") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsDetachEndpointsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsDetachEndpointsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupsListEndpointsRequest struct {
	// HealthStatus: Optional query parameter for showing the health status
	// of each network endpoint. Valid options are SKIP or SHOW. If you
	// don't specifiy this parameter, the health status of network endpoints
	// will not be provided.
	//
	// Possible values:
	//   "SHOW"
	//   "SKIP"
	HealthStatus string `json:"healthStatus,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HealthStatus") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthStatus") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsListEndpointsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsListEndpointsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupsListNetworkEndpoints struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NetworkEndpointWithHealthStatus resources.
	Items []*NetworkEndpointWithHealthStatus `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#networkEndpointGroupsListNetworkEndpoints for the list of
	// network endpoints in the specified network endpoint group.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NetworkEndpointGroupsListNetworkEndpointsWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsListNetworkEndpoints) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsListNetworkEndpoints
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkEndpointGroupsListNetworkEndpointsWarning: [Output Only]
// Informational warning message.
type NetworkEndpointGroupsListNetworkEndpointsWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NetworkEndpointGroupsListNetworkEndpointsWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsListNetworkEndpointsWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsListNetworkEndpointsWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupsListNetworkEndpointsWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsListNetworkEndpointsWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsListNetworkEndpointsWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupsScopedList struct {
	// NetworkEndpointGroups: [Output Only] The list of network endpoint
	// groups that are contained in this scope.
	NetworkEndpointGroups []*NetworkEndpointGroup `json:"networkEndpointGroups,omitempty"`

	// Warning: [Output Only] An informational warning that replaces the
	// list of network endpoint groups when the list is empty.
	Warning *NetworkEndpointGroupsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "NetworkEndpointGroups") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NetworkEndpointGroups") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkEndpointGroupsScopedListWarning: [Output Only] An
// informational warning that replaces the list of network endpoint
// groups when the list is empty.
type NetworkEndpointGroupsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NetworkEndpointGroupsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointGroupsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointGroupsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointGroupsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkEndpointWithHealthStatus struct {
	// Healths: [Output only] The health status of network endpoint;
	Healths []*HealthStatusForNetworkEndpoint `json:"healths,omitempty"`

	// NetworkEndpoint: [Output only] The network endpoint;
	NetworkEndpoint *NetworkEndpoint `json:"networkEndpoint,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Healths") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Healths") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkEndpointWithHealthStatus) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkEndpointWithHealthStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkInterface: A network interface resource attached to an
// instance.
type NetworkInterface struct {
	// AccessConfigs: An array of configurations for this interface.
	// Currently, only one access config, ONE_TO_ONE_NAT, is supported. If
	// there are no accessConfigs specified, then this instance will have no
	// external internet access.
	AccessConfigs []*AccessConfig `json:"accessConfigs,omitempty"`

	// AliasIpRanges: An array of alias IP ranges for this network
	// interface. You can only specify this field for network interfaces in
	// VPC networks.
	AliasIpRanges []*AliasIpRange `json:"aliasIpRanges,omitempty"`

	// Fingerprint: Fingerprint hash of contents stored in this network
	// interface. This field will be ignored when inserting an Instance or
	// adding a NetworkInterface. An up-to-date fingerprint must be provided
	// in order to update the NetworkInterface, otherwise the request will
	// fail with error 412 conditionNotMet.
	Fingerprint string `json:"fingerprint,omitempty"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#networkInterface for network interfaces.
	Kind string `json:"kind,omitempty"`

	// Name: [Output Only] The name of the network interface, which is
	// generated by the server. For network devices, these are eth0, eth1,
	// etc.
	Name string `json:"name,omitempty"`

	// Network: URL of the network resource for this instance. When creating
	// an instance, if neither the network nor the subnetwork is specified,
	// the default network global/networks/default is used; if the network
	// is not specified but the subnetwork is specified, the network is
	// inferred.
	//
	// If you specify this property, you can specify the network as a full
	// or partial URL. For example, the following are all valid URLs:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/global/networks/network
	// - projects/project/global/networks/network
	// - global/networks/default
	Network string `json:"network,omitempty"`

	// NetworkIP: An IPv4 internal IP address to assign to the instance for
	// this network interface. If not specified by the user, an unused
	// internal IP is assigned by the system.
	NetworkIP string `json:"networkIP,omitempty"`

	// Subnetwork: The URL of the Subnetwork resource for this instance. If
	// the network resource is in legacy mode, do not specify this field. If
	// the network is in auto subnet mode, specifying the subnetwork is
	// optional. If the network is in custom subnet mode, specifying the
	// subnetwork is required. If you specify this field, you can specify
	// the subnetwork as a full or partial URL. For example, the following
	// are all valid URLs:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/regions/region/subnetworks/subnetwork
	// - regions/region/subnetworks/subnetwork
	Subnetwork string `json:"subnetwork,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccessConfigs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AccessConfigs") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkInterface) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkInterface
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkList: Contains a list of networks.
type NetworkList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Network resources.
	Items []*Network `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#networkList for
	// lists of networks.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NetworkListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkList) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkListWarning: [Output Only] Informational warning message.
type NetworkListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NetworkListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkPeering: A network peering attached to a network resource. The
// message includes the peering name, peer network, peering state, and a
// flag indicating whether Google Compute Engine should automatically
// create routes for the peering.
type NetworkPeering struct {
	// AutoCreateRoutes: This field will be deprecated soon. Use the
	// exchange_subnet_routes field instead. Indicates whether full mesh
	// connectivity is created and managed automatically between peered
	// networks. Currently this field should always be true since Google
	// Compute Engine will automatically create and manage subnetwork routes
	// between two networks when peering state is ACTIVE.
	AutoCreateRoutes bool `json:"autoCreateRoutes,omitempty"`

	// ExchangeSubnetRoutes: Indicates whether full mesh connectivity is
	// created and managed automatically between peered networks. Currently
	// this field should always be true since Google Compute Engine will
	// automatically create and manage subnetwork routes between two
	// networks when peering state is ACTIVE.
	ExchangeSubnetRoutes bool `json:"exchangeSubnetRoutes,omitempty"`

	// ExportCustomRoutes: Whether to export the custom routes to peer
	// network.
	ExportCustomRoutes bool `json:"exportCustomRoutes,omitempty"`

	// ImportCustomRoutes: Whether to import the custom routes from peer
	// network.
	ImportCustomRoutes bool `json:"importCustomRoutes,omitempty"`

	// Name: Name of this peering. Provided by the client when the peering
	// is created. The name must comply with RFC1035. Specifically, the name
	// must be 1-63 characters long and match regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?`. The first character must be a lowercase
	// letter, and all the following characters must be a dash, lowercase
	// letter, or digit, except the last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Network: The URL of the peer network. It can be either full URL or
	// partial URL. The peer network may belong to a different project. If
	// the partial URL does not contain project, it is assumed that the peer
	// network is in the same project as the current network.
	Network string `json:"network,omitempty"`

	// State: [Output Only] State for the peering, either `ACTIVE` or
	// `INACTIVE`. The peering is `ACTIVE` when there's a matching
	// configuration in the peer network.
	//
	// Possible values:
	//   "ACTIVE"
	//   "INACTIVE"
	State string `json:"state,omitempty"`

	// StateDetails: [Output Only] Details about the current state of the
	// peering.
	StateDetails string `json:"stateDetails,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoCreateRoutes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoCreateRoutes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworkPeering) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkPeering
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkRoutingConfig: A routing configuration attached to a network
// resource. The message includes the list of routers associated with
// the network, and a flag indicating the type of routing behavior to
// enforce network-wide.
type NetworkRoutingConfig struct {
	// RoutingMode: The network-wide routing mode to use. If set to
	// REGIONAL, this network's Cloud Routers will only advertise routes
	// with subnets of this network in the same region as the router. If set
	// to GLOBAL, this network's Cloud Routers will advertise routes with
	// all subnets of this network, across regions.
	//
	// Possible values:
	//   "GLOBAL"
	//   "REGIONAL"
	RoutingMode string `json:"routingMode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RoutingMode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RoutingMode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkRoutingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkRoutingConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworksAddPeeringRequest struct {
	// AutoCreateRoutes: This field will be deprecated soon. Use
	// exchange_subnet_routes in network_peering instead. Indicates whether
	// full mesh connectivity is created and managed automatically between
	// peered networks. Currently this field should always be true since
	// Google Compute Engine will automatically create and manage subnetwork
	// routes between two networks when peering state is ACTIVE.
	AutoCreateRoutes bool `json:"autoCreateRoutes,omitempty"`

	// Name: Name of the peering, which should conform to RFC1035.
	Name string `json:"name,omitempty"`

	// NetworkPeering: Network peering parameters. In order to specify route
	// policies for peering using import and export custom routes, you must
	// specify all peering related parameters (name, peer network,
	// exchange_subnet_routes) in the network_peering field. The
	// corresponding fields in NetworksAddPeeringRequest will be deprecated
	// soon.
	NetworkPeering *NetworkPeering `json:"networkPeering,omitempty"`

	// PeerNetwork: URL of the peer network. It can be either full URL or
	// partial URL. The peer network may belong to a different project. If
	// the partial URL does not contain project, it is assumed that the peer
	// network is in the same project as the current network.
	PeerNetwork string `json:"peerNetwork,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoCreateRoutes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoCreateRoutes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworksAddPeeringRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NetworksAddPeeringRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworksRemovePeeringRequest struct {
	// Name: Name of the peering, which should conform to RFC1035.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworksRemovePeeringRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NetworksRemovePeeringRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworksUpdatePeeringRequest struct {
	NetworkPeering *NetworkPeering `json:"networkPeering,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NetworkPeering") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NetworkPeering") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworksUpdatePeeringRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NetworksUpdatePeeringRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeGroup: Represent a sole-tenant Node Group resource.
//
// A sole-tenant node is a physical server that is dedicated to hosting
// VM instances only for your specific project. Use sole-tenant nodes to
// keep your instances physically separated from instances in other
// projects, or to group your instances together on the same host
// hardware. For more information, read Sole-tenant nodes. (==
// resource_for beta.nodeGroups ==) (== resource_for v1.nodeGroups ==)
// NextID: 16
type NodeGroup struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] The type of the resource. Always
	// compute#nodeGroup for node group.
	Kind string `json:"kind,omitempty"`

	// Name: The name of the resource, provided by the client when initially
	// creating the resource. The resource name must be 1-63 characters
	// long, and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	// NodeTemplate: The URL of the node template to which this node group
	// belongs.
	NodeTemplate string `json:"nodeTemplate,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Size: [Output Only] The total number of nodes in the node group.
	Size int64 `json:"size,omitempty"`

	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "INVALID"
	//   "READY"
	Status string `json:"status,omitempty"`

	// Zone: [Output Only] The name of the zone where the node group
	// resides, such as us-central1-a.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroup) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NodeGroupsScopedList resources.
	Items map[string]NodeGroupsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always
	// compute#nodeGroupAggregatedList for aggregated lists of node groups.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NodeGroupAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeGroupAggregatedListWarning: [Output Only] Informational warning
// message.
type NodeGroupAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeGroupAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeGroupList: Contains a list of nodeGroups.
type NodeGroupList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NodeGroup resources.
	Items []*NodeGroup `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always compute#nodeGroupList for
	// lists of node groups.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NodeGroupListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeGroupListWarning: [Output Only] Informational warning message.
type NodeGroupListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeGroupListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupNode struct {
	// Instances: Instances scheduled on this node.
	Instances []string `json:"instances,omitempty"`

	// Name: The name of the node.
	Name string `json:"name,omitempty"`

	// NodeType: The type of this node.
	NodeType string `json:"nodeType,omitempty"`

	// ServerBinding: Binding properties for the physical server.
	ServerBinding *ServerBinding `json:"serverBinding,omitempty"`

	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "INVALID"
	//   "READY"
	//   "REPAIRING"
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupNode) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupNode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupsAddNodesRequest struct {
	// AdditionalNodeCount: Count of additional nodes to be added to the
	// node group.
	AdditionalNodeCount int64 `json:"additionalNodeCount,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdditionalNodeCount")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdditionalNodeCount") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsAddNodesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsAddNodesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupsDeleteNodesRequest struct {
	// Nodes: Names of the nodes to delete.
	Nodes []string `json:"nodes,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Nodes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Nodes") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsDeleteNodesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsDeleteNodesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupsListNodes struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Node resources.
	Items []*NodeGroupNode `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute.nodeGroupsListNodes for the list of nodes in the specified
	// node group.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NodeGroupsListNodesWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsListNodes) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsListNodes
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeGroupsListNodesWarning: [Output Only] Informational warning
// message.
type NodeGroupsListNodesWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeGroupsListNodesWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsListNodesWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsListNodesWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupsListNodesWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsListNodesWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsListNodesWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupsScopedList struct {
	// NodeGroups: [Output Only] A list of node groups contained in this
	// scope.
	NodeGroups []*NodeGroup `json:"nodeGroups,omitempty"`

	// Warning: [Output Only] An informational warning that appears when the
	// nodeGroup list is empty.
	Warning *NodeGroupsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NodeGroups") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NodeGroups") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeGroupsScopedListWarning: [Output Only] An informational warning
// that appears when the nodeGroup list is empty.
type NodeGroupsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeGroupsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeGroupsSetNodeTemplateRequest struct {
	// NodeTemplate: Full or partial URL of the node template resource to be
	// updated for this node group.
	NodeTemplate string `json:"nodeTemplate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NodeTemplate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NodeTemplate") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeGroupsSetNodeTemplateRequest) MarshalJSON() ([]byte, error) {
	type NoMethod NodeGroupsSetNodeTemplateRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTemplate: Represent a sole-tenant Node Template resource.
//
// You can use a template to define properties for nodes in a node
// group. For more information, read Creating node groups and instances.
// (== resource_for beta.nodeTemplates ==) (== resource_for
// v1.nodeTemplates ==) (== NextID: 16 ==)
type NodeTemplate struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] The type of the resource. Always
	// compute#nodeTemplate for node templates.
	Kind string `json:"kind,omitempty"`

	// Name: The name of the resource, provided by the client when initially
	// creating the resource. The resource name must be 1-63 characters
	// long, and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	// NodeAffinityLabels: Labels to use for node affinity, which will be
	// used in instance scheduling.
	NodeAffinityLabels map[string]string `json:"nodeAffinityLabels,omitempty"`

	// NodeType: The node type to use for nodes group that are created from
	// this template.
	NodeType string `json:"nodeType,omitempty"`

	// NodeTypeFlexibility: The flexible properties of the desired node
	// type. Node groups that use this node template will create nodes of a
	// type that matches these properties.
	//
	// This field is mutually exclusive with the node_type property; you can
	// only define one or the other, but not both.
	NodeTypeFlexibility *NodeTemplateNodeTypeFlexibility `json:"nodeTypeFlexibility,omitempty"`

	// Region: [Output Only] The name of the region where the node template
	// resides, such as us-central1.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServerBinding: Sets the binding properties for the physical server.
	// Valid values include:
	// - [Default] RESTART_NODE_ON_ANY_SERVER: Restarts VMs on any available
	// physical server
	// - RESTART_NODE_ON_MINIMAL_SERVER: Restarts VMs on the same physical
	// server whenever possible
	//
	// See Sole-tenant node options for more information.
	ServerBinding *ServerBinding `json:"serverBinding,omitempty"`

	// Status: [Output Only] The status of the node template. One of the
	// following values: CREATING, READY, and DELETING.
	//
	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "INVALID"
	//   "READY"
	Status string `json:"status,omitempty"`

	// StatusMessage: [Output Only] An optional, human-readable explanation
	// of the status.
	StatusMessage string `json:"statusMessage,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplate) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTemplateAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NodeTemplatesScopedList resources.
	Items map[string]NodeTemplatesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always
	// compute#nodeTemplateAggregatedList for aggregated lists of node
	// templates.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NodeTemplateAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplateAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplateAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTemplateAggregatedListWarning: [Output Only] Informational
// warning message.
type NodeTemplateAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeTemplateAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplateAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplateAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTemplateAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplateAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplateAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTemplateList: Contains a list of node templates.
type NodeTemplateList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NodeTemplate resources.
	Items []*NodeTemplate `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always compute#nodeTemplateList
	// for lists of node templates.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NodeTemplateListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplateList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplateList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTemplateListWarning: [Output Only] Informational warning message.
type NodeTemplateListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeTemplateListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplateListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplateListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTemplateListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplateListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplateListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTemplateNodeTypeFlexibility struct {
	Cpus string `json:"cpus,omitempty"`

	LocalSsd string `json:"localSsd,omitempty"`

	Memory string `json:"memory,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Cpus") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Cpus") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplateNodeTypeFlexibility) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplateNodeTypeFlexibility
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTemplatesScopedList struct {
	// NodeTemplates: [Output Only] A list of node templates contained in
	// this scope.
	NodeTemplates []*NodeTemplate `json:"nodeTemplates,omitempty"`

	// Warning: [Output Only] An informational warning that appears when the
	// node templates list is empty.
	Warning *NodeTemplatesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NodeTemplates") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NodeTemplates") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplatesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplatesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTemplatesScopedListWarning: [Output Only] An informational
// warning that appears when the node templates list is empty.
type NodeTemplatesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeTemplatesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplatesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplatesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTemplatesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTemplatesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTemplatesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeType: Represent a sole-tenant Node Type resource.
//
// Each node within a node group must have a node type. A node type
// specifies the total amount of cores and memory for that node.
// Currently, the only available node type is n1-node-96-624 node type
// that has 96 vCPUs and 624 GB of memory, available in multiple zones.
// For more information read Node types. (== resource_for beta.nodeTypes
// ==) (== resource_for v1.nodeTypes ==)
type NodeType struct {
	// CpuPlatform: [Output Only] The CPU platform used by this node type.
	CpuPlatform string `json:"cpuPlatform,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Deprecated: [Output Only] The deprecation status associated with this
	// node type.
	Deprecated *DeprecationStatus `json:"deprecated,omitempty"`

	// Description: [Output Only] An optional textual description of the
	// resource.
	Description string `json:"description,omitempty"`

	// GuestCpus: [Output Only] The number of virtual CPUs that are
	// available to the node type.
	GuestCpus int64 `json:"guestCpus,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] The type of the resource. Always compute#nodeType
	// for node types.
	Kind string `json:"kind,omitempty"`

	// LocalSsdGb: [Output Only] Local SSD available to the node type,
	// defined in GB.
	LocalSsdGb int64 `json:"localSsdGb,omitempty"`

	// MemoryMb: [Output Only] The amount of physical memory available to
	// the node type, defined in MB.
	MemoryMb int64 `json:"memoryMb,omitempty"`

	// Name: [Output Only] Name of the resource.
	Name string `json:"name,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Zone: [Output Only] The name of the zone where the node type resides,
	// such as us-central1-a.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CpuPlatform") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CpuPlatform") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeType) MarshalJSON() ([]byte, error) {
	type NoMethod NodeType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTypeAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NodeTypesScopedList resources.
	Items map[string]NodeTypesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always
	// compute#nodeTypeAggregatedList for aggregated lists of node types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NodeTypeAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypeAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypeAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTypeAggregatedListWarning: [Output Only] Informational warning
// message.
type NodeTypeAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeTypeAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypeAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypeAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTypeAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypeAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypeAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTypeList: Contains a list of node types.
type NodeTypeList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of NodeType resources.
	Items []*NodeType `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always compute#nodeTypeList for
	// lists of node types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *NodeTypeListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypeList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypeList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTypeListWarning: [Output Only] Informational warning message.
type NodeTypeListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeTypeListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypeListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypeListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTypeListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypeListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypeListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTypesScopedList struct {
	// NodeTypes: [Output Only] A list of node types contained in this
	// scope.
	NodeTypes []*NodeType `json:"nodeTypes,omitempty"`

	// Warning: [Output Only] An informational warning that appears when the
	// node types list is empty.
	Warning *NodeTypesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NodeTypes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NodeTypes") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NodeTypesScopedListWarning: [Output Only] An informational warning
// that appears when the node types list is empty.
type NodeTypesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*NodeTypesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NodeTypesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NodeTypesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod NodeTypesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Operation: Represents an Operation resource.
//
// You can use an operation resource to manage asynchronous API
// requests. For more information, read Handling API
// responses.
//
// Operations can be global, regional or zonal.
// - For global operations, use the globalOperations resource.
// - For regional operations, use the regionOperations resource.
// - For zonal operations, use the zonalOperations resource.
//
// For more information, read  Global, Regional, and Zonal Resources.
// (== resource_for v1.globalOperations ==) (== resource_for
// beta.globalOperations ==) (== resource_for v1.regionOperations ==)
// (== resource_for beta.regionOperations ==) (== resource_for
// v1.zoneOperations ==) (== resource_for beta.zoneOperations ==)
type Operation struct {
	// ClientOperationId: [Output Only] The value of `requestId` if you
	// provided it in the request. Not present otherwise.
	ClientOperationId string `json:"clientOperationId,omitempty"`

	// CreationTimestamp: [Deprecated] This field is deprecated.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: [Output Only] A textual description of the operation,
	// which is set when the operation is created.
	Description string `json:"description,omitempty"`

	// EndTime: [Output Only] The time that this operation was completed.
	// This value is in RFC3339 text format.
	EndTime string `json:"endTime,omitempty"`

	// Error: [Output Only] If errors are generated during processing of the
	// operation, this field will be populated.
	Error *OperationError `json:"error,omitempty"`

	// HttpErrorMessage: [Output Only] If the operation fails, this field
	// contains the HTTP error message that was returned, such as NOT FOUND.
	HttpErrorMessage string `json:"httpErrorMessage,omitempty"`

	// HttpErrorStatusCode: [Output Only] If the operation fails, this field
	// contains the HTTP error status code that was returned. For example, a
	// 404 means the resource was not found.
	HttpErrorStatusCode int64 `json:"httpErrorStatusCode,omitempty"`

	// Id: [Output Only] The unique identifier for the operation. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// InsertTime: [Output Only] The time that this operation was requested.
	// This value is in RFC3339 text format.
	InsertTime string `json:"insertTime,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#operation
	// for Operation resources.
	Kind string `json:"kind,omitempty"`

	// Name: [Output Only] Name of the operation.
	Name string `json:"name,omitempty"`

	// OperationType: [Output Only] The type of operation, such as insert,
	// update, or delete, and so on.
	OperationType string `json:"operationType,omitempty"`

	// Progress: [Output Only] An optional progress indicator that ranges
	// from 0 to 100. There is no requirement that this be linear or support
	// any granularity of operations. This should not be used to guess when
	// the operation will be complete. This number should monotonically
	// increase as the operation progresses.
	Progress int64 `json:"progress,omitempty"`

	// Region: [Output Only] The URL of the region where the operation
	// resides. Only applicable when performing regional operations.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// StartTime: [Output Only] The time that this operation was started by
	// the server. This value is in RFC3339 text format.
	StartTime string `json:"startTime,omitempty"`

	// Status: [Output Only] The status of the operation, which can be one
	// of the following: PENDING, RUNNING, or DONE.
	//
	// Possible values:
	//   "DONE"
	//   "PENDING"
	//   "RUNNING"
	Status string `json:"status,omitempty"`

	// StatusMessage: [Output Only] An optional textual description of the
	// current status of the operation.
	StatusMessage string `json:"statusMessage,omitempty"`

	// TargetId: [Output Only] The unique target ID, which identifies a
	// specific incarnation of the target resource.
	TargetId uint64 `json:"targetId,omitempty,string"`

	// TargetLink: [Output Only] The URL of the resource that the operation
	// modifies. For operations related to creating a snapshot, this points
	// to the persistent disk that the snapshot was created from.
	TargetLink string `json:"targetLink,omitempty"`

	// User: [Output Only] User who requested the operation, for example:
	// user@example.com.
	User string `json:"user,omitempty"`

	// Warnings: [Output Only] If warning messages are generated during
	// processing of the operation, this field will be populated.
	Warnings []*OperationWarnings `json:"warnings,omitempty"`

	// Zone: [Output Only] The URL of the zone where the operation resides.
	// Only applicable when performing per-zone operations.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ClientOperationId")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ClientOperationId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OperationError: [Output Only] If errors are generated during
// processing of the operation, this field will be populated.
type OperationError struct {
	// Errors: [Output Only] The array of errors encountered while
	// processing this operation.
	Errors []*OperationErrorErrors `json:"errors,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Errors") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Errors") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationError) MarshalJSON() ([]byte, error) {
	type NoMethod OperationError
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationErrorErrors struct {
	// Code: [Output Only] The error type identifier for this error.
	Code string `json:"code,omitempty"`

	// Location: [Output Only] Indicates the field in the request that
	// caused the error. This property is optional.
	Location string `json:"location,omitempty"`

	// Message: [Output Only] An optional, human-readable error message.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationErrorErrors) MarshalJSON() ([]byte, error) {
	type NoMethod OperationErrorErrors
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationWarnings struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*OperationWarningsData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationWarnings) MarshalJSON() ([]byte, error) {
	type NoMethod OperationWarnings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationWarningsData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationWarningsData) MarshalJSON() ([]byte, error) {
	type NoMethod OperationWarningsData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationAggregatedList struct {
	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id string `json:"id,omitempty"`

	// Items: [Output Only] A map of scoped operation lists.
	Items map[string]OperationsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#operationAggregatedList for aggregated lists of operations.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *OperationAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod OperationAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OperationAggregatedListWarning: [Output Only] Informational warning
// message.
type OperationAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*OperationAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod OperationAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod OperationAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OperationList: Contains a list of Operation resources.
type OperationList struct {
	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id string `json:"id,omitempty"`

	// Items: [Output Only] A list of Operation resources.
	Items []*Operation `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#operations for
	// Operations resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *OperationListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationList) MarshalJSON() ([]byte, error) {
	type NoMethod OperationList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OperationListWarning: [Output Only] Informational warning message.
type OperationListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*OperationListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod OperationListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod OperationListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationsScopedList struct {
	// Operations: [Output Only] A list of operations contained in this
	// scope.
	Operations []*Operation `json:"operations,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of operations when the list is empty.
	Warning *OperationsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Operations") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Operations") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod OperationsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OperationsScopedListWarning: [Output Only] Informational warning
// which replaces the list of operations when the list is empty.
type OperationsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*OperationsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod OperationsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type OperationsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OperationsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod OperationsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OutlierDetection: Settings controlling the eviction of unhealthy
// hosts from the load balancing pool for the backend service.
type OutlierDetection struct {
	// BaseEjectionTime: The base time that a host is ejected for. The real
	// ejection time is equal to the base ejection time multiplied by the
	// number of times the host has been ejected. Defaults to 30000ms or
	// 30s.
	BaseEjectionTime *Duration `json:"baseEjectionTime,omitempty"`

	// ConsecutiveErrors: Number of errors before a host is ejected from the
	// connection pool. When the backend host is accessed over HTTP, a 5xx
	// return code qualifies as an error. Defaults to 5.
	ConsecutiveErrors int64 `json:"consecutiveErrors,omitempty"`

	// ConsecutiveGatewayFailure: The number of consecutive gateway failures
	// (502, 503, 504 status or connection errors that are mapped to one of
	// those status codes) before a consecutive gateway failure ejection
	// occurs. Defaults to 3.
	ConsecutiveGatewayFailure int64 `json:"consecutiveGatewayFailure,omitempty"`

	// EnforcingConsecutiveErrors: The percentage chance that a host will be
	// actually ejected when an outlier status is detected through
	// consecutive 5xx. This setting can be used to disable ejection or to
	// ramp it up slowly. Defaults to 0.
	EnforcingConsecutiveErrors int64 `json:"enforcingConsecutiveErrors,omitempty"`

	// EnforcingConsecutiveGatewayFailure: The percentage chance that a host
	// will be actually ejected when an outlier status is detected through
	// consecutive gateway failures. This setting can be used to disable
	// ejection or to ramp it up slowly. Defaults to 100.
	EnforcingConsecutiveGatewayFailure int64 `json:"enforcingConsecutiveGatewayFailure,omitempty"`

	// EnforcingSuccessRate: The percentage chance that a host will be
	// actually ejected when an outlier status is detected through success
	// rate statistics. This setting can be used to disable ejection or to
	// ramp it up slowly. Defaults to 100.
	EnforcingSuccessRate int64 `json:"enforcingSuccessRate,omitempty"`

	// Interval: Time interval between ejection sweep analysis. This can
	// result in both new ejections as well as hosts being returned to
	// service. Defaults to 1 seconds.
	Interval *Duration `json:"interval,omitempty"`

	// MaxEjectionPercent: Maximum percentage of hosts in the load balancing
	// pool for the backend service that can be ejected. Defaults to 50%.
	MaxEjectionPercent int64 `json:"maxEjectionPercent,omitempty"`

	// SuccessRateMinimumHosts: The number of hosts in a cluster that must
	// have enough request volume to detect success rate outliers. If the
	// number of hosts is less than this setting, outlier detection via
	// success rate statistics is not performed for any host in the cluster.
	// Defaults to 5.
	SuccessRateMinimumHosts int64 `json:"successRateMinimumHosts,omitempty"`

	// SuccessRateRequestVolume: The minimum number of total requests that
	// must be collected in one interval (as defined by the interval
	// duration above) to include this host in success rate based outlier
	// detection. If the volume is lower than this setting, outlier
	// detection via success rate statistics is not performed for that host.
	// Defaults to 100.
	SuccessRateRequestVolume int64 `json:"successRateRequestVolume,omitempty"`

	// SuccessRateStdevFactor: This factor is used to determine the ejection
	// threshold for success rate outlier ejection. The ejection threshold
	// is the difference between the mean success rate, and the product of
	// this factor and the standard deviation of the mean success rate: mean
	// - (stdev * success_rate_stdev_factor). This factor is divided by a
	// thousand to get a double. That is, if the desired factor is 1.9, the
	// runtime value should be 1900. Defaults to 1900.
	SuccessRateStdevFactor int64 `json:"successRateStdevFactor,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BaseEjectionTime") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BaseEjectionTime") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *OutlierDetection) MarshalJSON() ([]byte, error) {
	type NoMethod OutlierDetection
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PathMatcher: A matcher for the path portion of the URL. The
// BackendService from the longest-matched rule will serve the URL. If
// no rule was matched, the default service will be used.
type PathMatcher struct {
	// DefaultRouteAction: defaultRouteAction takes effect when none of the
	// pathRules or routeRules match. The load balancer performs advanced
	// routing actions like URL rewrites, header transformations, etc. prior
	// to forwarding the request to the selected backend. If
	// defaultRouteAction specifies any weightedBackendServices,
	// defaultService must not be set. Conversely if defaultService is set,
	// defaultRouteAction cannot contain any  weightedBackendServices.
	// Only one of defaultRouteAction or defaultUrlRedirect must be set.
	DefaultRouteAction *HttpRouteAction `json:"defaultRouteAction,omitempty"`

	// DefaultService: The full or partial URL to the BackendService
	// resource. This will be used if none of the pathRules or routeRules
	// defined by this PathMatcher are matched. For example, the following
	// are all valid URLs to a BackendService resource:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/global/backendServices/backendService
	// - compute/v1/projects/project/global/backendServices/backendService
	//
	// - global/backendServices/backendService  If defaultRouteAction is
	// additionally specified, advanced routing actions like URL Rewrites,
	// etc. take effect prior to sending the request to the backend.
	// However, if defaultService is specified, defaultRouteAction cannot
	// contain any weightedBackendServices. Conversely, if
	// defaultRouteAction specifies any weightedBackendServices,
	// defaultService must not be specified.
	// Only one of defaultService, defaultUrlRedirect  or
	// defaultRouteAction.weightedBackendService must be set.
	// Authorization requires one or more of the following Google IAM
	// permissions on the specified resource default_service:
	// - compute.backendBuckets.use
	// - compute.backendServices.use
	DefaultService string `json:"defaultService,omitempty"`

	// DefaultUrlRedirect: When when none of the specified pathRules or
	// routeRules match, the request is redirected to a URL specified by
	// defaultUrlRedirect.
	// If defaultUrlRedirect is specified, defaultService or
	// defaultRouteAction must not be set.
	DefaultUrlRedirect *HttpRedirectAction `json:"defaultUrlRedirect,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// HeaderAction: Specifies changes to request and response headers that
	// need to take effect for the selected backendService.
	// HeaderAction specified here are applied after the matching
	// HttpRouteRule HeaderAction and before the HeaderAction in the UrlMap
	HeaderAction *HttpHeaderAction `json:"headerAction,omitempty"`

	// Name: The name to which this PathMatcher is referred by the HostRule.
	Name string `json:"name,omitempty"`

	// PathRules: The list of path rules. Use this list instead of
	// routeRules when routing based on simple path matching is all that's
	// required. The order by which path rules are specified does not
	// matter. Matches are always done on the longest-path-first basis.
	// For example: a pathRule with a path /a/b/c/* will match before /a/b/*
	// irrespective of the order in which those paths appear in this
	// list.
	// Within a given pathMatcher, only one of pathRules or routeRules must
	// be set.
	PathRules []*PathRule `json:"pathRules,omitempty"`

	// RouteRules: The list of ordered HTTP route rules. Use this list
	// instead of pathRules when advanced route matching and routing actions
	// are desired. The order of specifying routeRules matters: the first
	// rule that matches will cause its specified routing action to take
	// effect.
	// Within a given pathMatcher, only one of pathRules or routeRules must
	// be set.
	// routeRules are not supported in UrlMaps intended for External Load
	// balancers.
	RouteRules []*HttpRouteRule `json:"routeRules,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DefaultRouteAction")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DefaultRouteAction") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *PathMatcher) MarshalJSON() ([]byte, error) {
	type NoMethod PathMatcher
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PathRule: A path-matching rule for a URL. If matched, will use the
// specified BackendService to handle the traffic arriving at this URL.
type PathRule struct {
	// Paths: The list of path patterns to match. Each must start with / and
	// the only place a * is allowed is at the end following a /. The string
	// fed to the path matcher does not include any text after the first ?
	// or #, and those chars are not allowed here.
	Paths []string `json:"paths,omitempty"`

	// RouteAction: In response to a matching path, the load balancer
	// performs advanced routing actions like URL rewrites, header
	// transformations, etc. prior to forwarding the request to the selected
	// backend. If routeAction specifies any  weightedBackendServices,
	// service must not be set. Conversely if service is set, routeAction
	// cannot contain any  weightedBackendServices.
	// Only one of routeAction or urlRedirect must be set.
	RouteAction *HttpRouteAction `json:"routeAction,omitempty"`

	// Service: The full or partial URL of the backend service resource to
	// which traffic is directed if this rule is matched. If routeAction is
	// additionally specified, advanced routing actions like URL Rewrites,
	// etc. take effect prior to sending the request to the backend.
	// However, if service is specified, routeAction cannot contain any
	// weightedBackendService s. Conversely, if routeAction specifies any
	// weightedBackendServices, service must not be specified.
	// Only one of urlRedirect, service or
	// routeAction.weightedBackendService must be set.
	Service string `json:"service,omitempty"`

	// UrlRedirect: When a path pattern is matched, the request is
	// redirected to a URL specified by urlRedirect.
	// If urlRedirect is specified, service or routeAction must not be set.
	UrlRedirect *HttpRedirectAction `json:"urlRedirect,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Paths") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Paths") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PathRule) MarshalJSON() ([]byte, error) {
	type NoMethod PathRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Policy: Defines an Identity and Access Management (IAM) policy. It is
// used to specify access control policies for Cloud Platform
// resources.
//
//
//
// A `Policy` is a collection of `bindings`. A `binding` binds one or
// more `members` to a single `role`. Members can be user accounts,
// service accounts, Google groups, and domains (such as G Suite). A
// `role` is a named list of permissions (defined by IAM or configured
// by users). A `binding` can optionally specify a `condition`, which is
// a logic expression that further constrains the role binding based on
// attributes about the request and/or target resource.
//
// **JSON Example**
//
// { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin",
// "members": [ "user:mike@example.com", "group:admins@example.com",
// "domain:google.com",
// "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, {
// "role": "roles/resourcemanager.organizationViewer", "members":
// ["user:eve@example.com"], "condition": { "title": "expirable access",
// "description": "Does not grant access after Sep 2020", "expression":
// "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ]
// }
//
// **YAML Example**
//
// bindings: - members: - user:mike@example.com -
// group:admins@example.com - domain:google.com -
// serviceAccount:my-project-id@appspot.gserviceaccount.com role:
// roles/resourcemanager.organizationAdmin - members: -
// user:eve@example.com role: roles/resourcemanager.organizationViewer
// condition: title: expirable access description: Does not grant access
// after Sep 2020 expression: request.time <
// timestamp('2020-10-01T00:00:00.000Z')
//
// For a description of IAM and its features, see the [IAM developer's
// guide](https://cloud.google.com/iam/docs).
type Policy struct {
	// AuditConfigs: Specifies cloud audit logging configuration for this
	// policy.
	AuditConfigs []*AuditConfig `json:"auditConfigs,omitempty"`

	// Bindings: Associates a list of `members` to a `role`. Optionally may
	// specify a `condition` that determines when binding is in effect.
	// `bindings` with no members will result in an error.
	Bindings []*Binding `json:"bindings,omitempty"`

	// Etag: `etag` is used for optimistic concurrency control as a way to
	// help prevent simultaneous updates of a policy from overwriting each
	// other. It is strongly suggested that systems make use of the `etag`
	// in the read-modify-write cycle to perform policy updates in order to
	// avoid race conditions: An `etag` is returned in the response to
	// `getIamPolicy`, and systems are expected to put that etag in the
	// request to `setIamPolicy` to ensure that their change will be applied
	// to the same version of the policy.
	//
	// If no `etag` is provided in the call to `setIamPolicy`, then the
	// existing policy is overwritten. Due to blind-set semantics of an
	// etag-less policy, 'setIamPolicy' will not fail even if either of
	// incoming or stored policy does not meet the version requirements.
	Etag string `json:"etag,omitempty"`

	IamOwned bool `json:"iamOwned,omitempty"`

	// Rules: If more than one rule is specified, the rules are applied in
	// the following manner: - All matching LOG rules are always applied. -
	// If any DENY/DENY_WITH_LOG rule matches, permission is denied. Logging
	// will be applied if one or more matching rule requires logging. -
	// Otherwise, if any ALLOW/ALLOW_WITH_LOG rule matches, permission is
	// granted. Logging will be applied if one or more matching rule
	// requires logging. - Otherwise, if no rule applies, permission is
	// denied.
	Rules []*Rule `json:"rules,omitempty"`

	// Version: Specifies the format of the policy.
	//
	// Valid values are 0, 1, and 3. Requests specifying an invalid value
	// will be rejected.
	//
	// Operations affecting conditional bindings must specify version 3.
	// This can be either setting a conditional policy, modifying a
	// conditional binding, or removing a conditional binding from the
	// stored conditional policy. Operations on non-conditional policies may
	// specify any valid value or leave the field unset.
	//
	// If no etag is provided in the call to `setIamPolicy`, any version
	// compliance checks on the incoming and/or stored policy is skipped.
	Version int64 `json:"version,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AuditConfigs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AuditConfigs") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Policy) MarshalJSON() ([]byte, error) {
	type NoMethod Policy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Project: Represents a Project resource.
//
// A project is used to organize resources in a Google Cloud Platform
// environment. For more information, read about the  Resource
// Hierarchy. (== resource_for v1.projects ==) (== resource_for
// beta.projects ==)
type Project struct {
	// CommonInstanceMetadata: Metadata key/value pairs available to all
	// instances contained in this project. See Custom metadata for more
	// information.
	CommonInstanceMetadata *Metadata `json:"commonInstanceMetadata,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// DefaultNetworkTier: This signifies the default network tier used for
	// configuring resources of the project and can only take the following
	// values: PREMIUM, STANDARD. Initially the default network tier is
	// PREMIUM.
	//
	// Possible values:
	//   "PREMIUM"
	//   "STANDARD"
	DefaultNetworkTier string `json:"defaultNetworkTier,omitempty"`

	// DefaultServiceAccount: [Output Only] Default service account used by
	// VMs running in this project.
	DefaultServiceAccount string `json:"defaultServiceAccount,omitempty"`

	// Description: An optional textual description of the resource.
	Description string `json:"description,omitempty"`

	// EnabledFeatures: Restricted features enabled for use on this project.
	EnabledFeatures []string `json:"enabledFeatures,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server. This is not the project ID, and
	// is just a unique ID used by Compute Engine to identify resources.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#project for
	// projects.
	Kind string `json:"kind,omitempty"`

	// Name: The project ID. For example: my-example-project. Use the
	// project ID to make requests to Compute Engine.
	Name string `json:"name,omitempty"`

	// Quotas: [Output Only] Quotas assigned to this project.
	Quotas []*Quota `json:"quotas,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// UsageExportLocation: The naming prefix for daily usage reports and
	// the Google Cloud Storage bucket where they are stored.
	UsageExportLocation *UsageExportLocation `json:"usageExportLocation,omitempty"`

	// XpnProjectStatus: [Output Only] The role this project has in a shared
	// VPC configuration. Currently only HOST projects are differentiated.
	//
	// Possible values:
	//   "HOST"
	//   "UNSPECIFIED_XPN_PROJECT_STATUS"
	XpnProjectStatus string `json:"xpnProjectStatus,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "CommonInstanceMetadata") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CommonInstanceMetadata")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Project) MarshalJSON() ([]byte, error) {
	type NoMethod Project
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectsDisableXpnResourceRequest struct {
	// XpnResource: Service resource (a.k.a service project) ID.
	XpnResource *XpnResourceId `json:"xpnResource,omitempty"`

	// ForceSendFields is a list of field names (e.g. "XpnResource") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "XpnResource") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ProjectsDisableXpnResourceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectsDisableXpnResourceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectsEnableXpnResourceRequest struct {
	// XpnResource: Service resource (a.k.a service project) ID.
	XpnResource *XpnResourceId `json:"xpnResource,omitempty"`

	// ForceSendFields is a list of field names (e.g. "XpnResource") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "XpnResource") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ProjectsEnableXpnResourceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectsEnableXpnResourceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectsGetXpnResources struct {
	// Kind: [Output Only] Type of resource. Always
	// compute#projectsGetXpnResources for lists of service resources (a.k.a
	// service projects)
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Resources: Service resources (a.k.a service projects) attached to
	// this project as their shared VPC host.
	Resources []*XpnResourceId `json:"resources,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ProjectsGetXpnResources) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectsGetXpnResources
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectsListXpnHostsRequest struct {
	// Organization: Optional organization ID managed by Cloud Resource
	// Manager, for which to list shared VPC host projects. If not
	// specified, the organization will be inferred from the project.
	Organization string `json:"organization,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Organization") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Organization") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ProjectsListXpnHostsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectsListXpnHostsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectsSetDefaultNetworkTierRequest struct {
	// NetworkTier: Default network tier to be set.
	//
	// Possible values:
	//   "PREMIUM"
	//   "STANDARD"
	NetworkTier string `json:"networkTier,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NetworkTier") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NetworkTier") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ProjectsSetDefaultNetworkTierRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectsSetDefaultNetworkTierRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Quota: A quotas entry.
type Quota struct {
	// Limit: [Output Only] Quota limit for this metric.
	Limit float64 `json:"limit,omitempty"`

	// Metric: [Output Only] Name of the quota metric.
	//
	// Possible values:
	//   "AUTOSCALERS"
	//   "BACKEND_BUCKETS"
	//   "BACKEND_SERVICES"
	//   "C2_CPUS"
	//   "COMMITMENTS"
	//   "COMMITTED_C2_CPUS"
	//   "COMMITTED_CPUS"
	//   "COMMITTED_LOCAL_SSD_TOTAL_GB"
	//   "COMMITTED_N2_CPUS"
	//   "COMMITTED_NVIDIA_K80_GPUS"
	//   "COMMITTED_NVIDIA_P100_GPUS"
	//   "COMMITTED_NVIDIA_P4_GPUS"
	//   "COMMITTED_NVIDIA_T4_GPUS"
	//   "COMMITTED_NVIDIA_V100_GPUS"
	//   "CPUS"
	//   "CPUS_ALL_REGIONS"
	//   "DISKS_TOTAL_GB"
	//   "EXTERNAL_VPN_GATEWAYS"
	//   "FIREWALLS"
	//   "FORWARDING_RULES"
	//   "GLOBAL_INTERNAL_ADDRESSES"
	//   "GPUS_ALL_REGIONS"
	//   "HEALTH_CHECKS"
	//   "IMAGES"
	//   "INSTANCES"
	//   "INSTANCE_GROUPS"
	//   "INSTANCE_GROUP_MANAGERS"
	//   "INSTANCE_TEMPLATES"
	//   "INTERCONNECTS"
	//   "INTERCONNECT_ATTACHMENTS_PER_REGION"
	//   "INTERCONNECT_ATTACHMENTS_TOTAL_MBPS"
	//   "INTERCONNECT_TOTAL_GBPS"
	//   "INTERNAL_ADDRESSES"
	//   "IN_USE_ADDRESSES"
	//   "IN_USE_BACKUP_SCHEDULES"
	//   "IN_USE_SNAPSHOT_SCHEDULES"
	//   "LOCAL_SSD_TOTAL_GB"
	//   "N2_CPUS"
	//   "NETWORKS"
	//   "NETWORK_ENDPOINT_GROUPS"
	//   "NVIDIA_K80_GPUS"
	//   "NVIDIA_P100_GPUS"
	//   "NVIDIA_P100_VWS_GPUS"
	//   "NVIDIA_P4_GPUS"
	//   "NVIDIA_P4_VWS_GPUS"
	//   "NVIDIA_T4_GPUS"
	//   "NVIDIA_T4_VWS_GPUS"
	//   "NVIDIA_V100_GPUS"
	//   "PREEMPTIBLE_CPUS"
	//   "PREEMPTIBLE_LOCAL_SSD_GB"
	//   "PREEMPTIBLE_NVIDIA_K80_GPUS"
	//   "PREEMPTIBLE_NVIDIA_P100_GPUS"
	//   "PREEMPTIBLE_NVIDIA_P100_VWS_GPUS"
	//   "PREEMPTIBLE_NVIDIA_P4_GPUS"
	//   "PREEMPTIBLE_NVIDIA_P4_VWS_GPUS"
	//   "PREEMPTIBLE_NVIDIA_T4_GPUS"
	//   "PREEMPTIBLE_NVIDIA_T4_VWS_GPUS"
	//   "PREEMPTIBLE_NVIDIA_V100_GPUS"
	//   "REGIONAL_AUTOSCALERS"
	//   "REGIONAL_INSTANCE_GROUP_MANAGERS"
	//   "RESERVATIONS"
	//   "RESOURCE_POLICIES"
	//   "ROUTERS"
	//   "ROUTES"
	//   "SECURITY_POLICIES"
	//   "SECURITY_POLICY_RULES"
	//   "SNAPSHOTS"
	//   "SSD_TOTAL_GB"
	//   "SSL_CERTIFICATES"
	//   "STATIC_ADDRESSES"
	//   "SUBNETWORKS"
	//   "TARGET_HTTPS_PROXIES"
	//   "TARGET_HTTP_PROXIES"
	//   "TARGET_INSTANCES"
	//   "TARGET_POOLS"
	//   "TARGET_SSL_PROXIES"
	//   "TARGET_TCP_PROXIES"
	//   "TARGET_VPN_GATEWAYS"
	//   "URL_MAPS"
	//   "VPN_GATEWAYS"
	//   "VPN_TUNNELS"
	Metric string `json:"metric,omitempty"`

	// Owner: [Output Only] Owning resource. This is the resource on which
	// this quota is applied.
	Owner string `json:"owner,omitempty"`

	// Usage: [Output Only] Current usage of this metric.
	Usage float64 `json:"usage,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Limit") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Limit") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Quota) MarshalJSON() ([]byte, error) {
	type NoMethod Quota
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Quota) UnmarshalJSON(data []byte) error {
	type NoMethod Quota
	var s1 struct {
		Limit gensupport.JSONFloat64 `json:"limit"`
		Usage gensupport.JSONFloat64 `json:"usage"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Limit = float64(s1.Limit)
	s.Usage = float64(s1.Usage)
	return nil
}

// Reference: Represents a reference to a resource.
type Reference struct {
	// Kind: [Output Only] Type of the resource. Always compute#reference
	// for references.
	Kind string `json:"kind,omitempty"`

	// ReferenceType: A description of the reference type with no implied
	// semantics. Possible values include:
	// - MEMBER_OF
	ReferenceType string `json:"referenceType,omitempty"`

	// Referrer: URL of the resource which refers to the target.
	Referrer string `json:"referrer,omitempty"`

	// Target: URL of the resource to which this reference points.
	Target string `json:"target,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Reference) MarshalJSON() ([]byte, error) {
	type NoMethod Reference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Region: Represents a Region resource.
//
// A region is a geographical area where a resource is located. For more
// information, read Regions and Zones. (== resource_for beta.regions
// ==) (== resource_for v1.regions ==)
type Region struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Deprecated: [Output Only] The deprecation status associated with this
	// region.
	Deprecated *DeprecationStatus `json:"deprecated,omitempty"`

	// Description: [Output Only] Textual description of the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#region for
	// regions.
	Kind string `json:"kind,omitempty"`

	// Name: [Output Only] Name of the resource.
	Name string `json:"name,omitempty"`

	// Quotas: [Output Only] Quotas assigned to this region.
	Quotas []*Quota `json:"quotas,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Status: [Output Only] Status of the region, either UP or DOWN.
	//
	// Possible values:
	//   "DOWN"
	//   "UP"
	Status string `json:"status,omitempty"`

	// Zones: [Output Only] A list of zones available in this region, in the
	// form of resource URLs.
	Zones []string `json:"zones,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Region) MarshalJSON() ([]byte, error) {
	type NoMethod Region
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionAutoscalerList: Contains a list of autoscalers.
type RegionAutoscalerList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Autoscaler resources.
	Items []*Autoscaler `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RegionAutoscalerListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionAutoscalerList) MarshalJSON() ([]byte, error) {
	type NoMethod RegionAutoscalerList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionAutoscalerListWarning: [Output Only] Informational warning
// message.
type RegionAutoscalerListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RegionAutoscalerListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionAutoscalerListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RegionAutoscalerListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionAutoscalerListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionAutoscalerListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RegionAutoscalerListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionDiskTypeList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of DiskType resources.
	Items []*DiskType `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#regionDiskTypeList for region disk types.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RegionDiskTypeListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionDiskTypeList) MarshalJSON() ([]byte, error) {
	type NoMethod RegionDiskTypeList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionDiskTypeListWarning: [Output Only] Informational warning
// message.
type RegionDiskTypeListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RegionDiskTypeListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionDiskTypeListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RegionDiskTypeListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionDiskTypeListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionDiskTypeListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RegionDiskTypeListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionDisksAddResourcePoliciesRequest struct {
	// ResourcePolicies: Resource policies to be added to this disk.
	ResourcePolicies []string `json:"resourcePolicies,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourcePolicies") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ResourcePolicies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RegionDisksAddResourcePoliciesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionDisksAddResourcePoliciesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionDisksRemoveResourcePoliciesRequest struct {
	// ResourcePolicies: Resource policies to be removed from this disk.
	ResourcePolicies []string `json:"resourcePolicies,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourcePolicies") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ResourcePolicies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RegionDisksRemoveResourcePoliciesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionDisksRemoveResourcePoliciesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionDisksResizeRequest struct {
	// SizeGb: The new size of the regional persistent disk, which is
	// specified in GB.
	SizeGb int64 `json:"sizeGb,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "SizeGb") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SizeGb") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionDisksResizeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionDisksResizeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionInstanceGroupList: Contains a list of InstanceGroup resources.
type RegionInstanceGroupList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceGroup resources.
	Items []*InstanceGroup `json:"items,omitempty"`

	// Kind: The resource type.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RegionInstanceGroupListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupList) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionInstanceGroupListWarning: [Output Only] Informational warning
// message.
type RegionInstanceGroupListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RegionInstanceGroupListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionInstanceGroupManagerList: Contains a list of managed instance
// groups.
type RegionInstanceGroupManagerList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceGroupManager resources.
	Items []*InstanceGroupManager `json:"items,omitempty"`

	// Kind: [Output Only] The resource type, which is always
	// compute#instanceGroupManagerList for a list of managed instance
	// groups that exist in th regional scope.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RegionInstanceGroupManagerListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagerList) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagerList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionInstanceGroupManagerListWarning: [Output Only] Informational
// warning message.
type RegionInstanceGroupManagerListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RegionInstanceGroupManagerListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagerListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagerListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupManagerListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagerListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagerListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupManagersAbandonInstancesRequest struct {
	// Instances: The URLs of one or more instances to abandon. This can be
	// a full URL or a partial URL, such as
	// zones/[ZONE]/instances/[INSTANCE_NAME].
	Instances []string `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagersAbandonInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagersAbandonInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupManagersDeleteInstancesRequest struct {
	// Instances: The URLs of one or more instances to delete. This can be a
	// full URL or a partial URL, such as
	// zones/[ZONE]/instances/[INSTANCE_NAME].
	Instances []string `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagersDeleteInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagersDeleteInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupManagersListInstancesResponse struct {
	// ManagedInstances: A list of managed instances.
	ManagedInstances []*ManagedInstance `json:"managedInstances,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ManagedInstances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ManagedInstances") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagersListInstancesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagersListInstancesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupManagersRecreateRequest struct {
	// Instances: The URLs of one or more instances to recreate. This can be
	// a full URL or a partial URL, such as
	// zones/[ZONE]/instances/[INSTANCE_NAME].
	Instances []string `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagersRecreateRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagersRecreateRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupManagersSetTargetPoolsRequest struct {
	// Fingerprint: Fingerprint of the target pools information, which is a
	// hash of the contents. This field is used for optimistic locking when
	// you update the target pool entries. This field is optional.
	Fingerprint string `json:"fingerprint,omitempty"`

	// TargetPools: The URL of all TargetPool resources to which instances
	// in the instanceGroup field are added. The target pools automatically
	// apply to all of the instances in the managed instance group.
	TargetPools []string `json:"targetPools,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fingerprint") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagersSetTargetPoolsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagersSetTargetPoolsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupManagersSetTemplateRequest struct {
	// InstanceTemplate: URL of the InstanceTemplate resource from which all
	// new instances will be created.
	InstanceTemplate string `json:"instanceTemplate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceTemplate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceTemplate") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupManagersSetTemplateRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupManagersSetTemplateRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupsListInstances struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of InstanceWithNamedPorts resources.
	Items []*InstanceWithNamedPorts `json:"items,omitempty"`

	// Kind: The resource type.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RegionInstanceGroupsListInstancesWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupsListInstances) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupsListInstances
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionInstanceGroupsListInstancesWarning: [Output Only] Informational
// warning message.
type RegionInstanceGroupsListInstancesWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RegionInstanceGroupsListInstancesWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupsListInstancesWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupsListInstancesWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupsListInstancesWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupsListInstancesWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupsListInstancesWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupsListInstancesRequest struct {
	// InstanceState: Instances in which state should be returned. Valid
	// options are: 'ALL', 'RUNNING'. By default, it lists all instances.
	//
	// Possible values:
	//   "ALL"
	//   "RUNNING"
	InstanceState string `json:"instanceState,omitempty"`

	// PortName: Name of port user is interested in. It is optional. If it
	// is set, only information about this ports will be returned. If it is
	// not set, all the named ports will be returned. Always lists all
	// instances.
	PortName string `json:"portName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupsListInstancesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupsListInstancesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionInstanceGroupsSetNamedPortsRequest struct {
	// Fingerprint: The fingerprint of the named ports information for this
	// instance group. Use this optional property to prevent conflicts when
	// multiple users change the named ports settings concurrently. Obtain
	// the fingerprint with the instanceGroups.get method. Then, include the
	// fingerprint in your request to ensure that you do not overwrite
	// changes that were applied from another concurrent request.
	Fingerprint string `json:"fingerprint,omitempty"`

	// NamedPorts: The list of named ports to set for this instance group.
	NamedPorts []*NamedPort `json:"namedPorts,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fingerprint") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionInstanceGroupsSetNamedPortsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionInstanceGroupsSetNamedPortsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionList: Contains a list of region resources.
type RegionList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Region resources.
	Items []*Region `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#regionList for
	// lists of regions.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RegionListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionList) MarshalJSON() ([]byte, error) {
	type NoMethod RegionList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionListWarning: [Output Only] Informational warning message.
type RegionListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RegionListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RegionListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RegionListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionSetLabelsRequest struct {
	// LabelFingerprint: The fingerprint of the previous set of labels for
	// this resource, used to detect conflicts. The fingerprint is initially
	// generated by Compute Engine and changes after every request to modify
	// or update labels. You must always provide an up-to-date fingerprint
	// hash in order to update or change labels. Make a get() request to the
	// resource to get the latest fingerprint.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: The labels to set for this resource.
	Labels map[string]string `json:"labels,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LabelFingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LabelFingerprint") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RegionSetLabelsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionSetLabelsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionSetPolicyRequest struct {
	// Bindings: Flatten Policy to create a backwacd compatible wire-format.
	// Deprecated. Use 'policy' to specify bindings.
	Bindings []*Binding `json:"bindings,omitempty"`

	// Etag: Flatten Policy to create a backward compatible wire-format.
	// Deprecated. Use 'policy' to specify the etag.
	Etag string `json:"etag,omitempty"`

	// Policy: REQUIRED: The complete policy to be applied to the
	// 'resource'. The size of the policy is limited to a few 10s of KB. An
	// empty policy is in general a valid policy but certain services (like
	// Projects) might reject them.
	Policy *Policy `json:"policy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bindings") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bindings") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionSetPolicyRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionSetPolicyRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionTargetHttpsProxiesSetSslCertificatesRequest struct {
	// SslCertificates: New set of SslCertificate resources to associate
	// with this TargetHttpsProxy resource. Currently exactly one
	// SslCertificate resource must be specified.
	SslCertificates []string `json:"sslCertificates,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SslCertificates") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SslCertificates") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RegionTargetHttpsProxiesSetSslCertificatesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionTargetHttpsProxiesSetSslCertificatesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RegionUrlMapsValidateRequest struct {
	// Resource: Content of the UrlMap to be validated.
	Resource *UrlMap `json:"resource,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Resource") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Resource") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegionUrlMapsValidateRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RegionUrlMapsValidateRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RequestMirrorPolicy: A policy that specifies how requests intended
// for the route's backends are shadowed to a separate mirrored backend
// service. Loadbalancer does not wait for responses from the shadow
// service. Prior to sending traffic to the shadow service, the host /
// authority header is suffixed with -shadow.
type RequestMirrorPolicy struct {
	// BackendService: The full or partial URL to the BackendService
	// resource being mirrored to.
	BackendService string `json:"backendService,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackendService") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackendService") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RequestMirrorPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod RequestMirrorPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Reservation: Represents a reservation resource. A reservation ensures
// that capacity is held in a specific zone even if the reserved VMs are
// not running. For more information, read  Reserving zonal resources.
// (== resource_for beta.reservations ==) (== resource_for
// v1.reservations ==)
type Reservation struct {
	// Commitment: [Output Only] Full or partial URL to a parent commitment.
	// This field displays for reservations that are tied to a commitment.
	Commitment string `json:"commitment,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#reservations
	// for reservations.
	Kind string `json:"kind,omitempty"`

	// Name: The name of the resource, provided by the client when initially
	// creating the resource. The resource name must be 1-63 characters
	// long, and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	// SelfLink: [Output Only] Server-defined fully-qualified URL for this
	// resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SpecificReservation: Reservation for instances with specific machine
	// shapes.
	SpecificReservation *AllocationSpecificSKUReservation `json:"specificReservation,omitempty"`

	// SpecificReservationRequired: Indicates whether the reservation can be
	// consumed by VMs with affinity for "any" reservation. If the field is
	// set, then only VMs that target the reservation by name can consume
	// from this reservation.
	SpecificReservationRequired bool `json:"specificReservationRequired,omitempty"`

	// Status: [Output Only] The status of the reservation.
	//
	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "INVALID"
	//   "READY"
	//   "UPDATING"
	Status string `json:"status,omitempty"`

	// Zone: Zone in which the reservation resides. A zone must be provided
	// if the reservation is created within a commitment.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Commitment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Commitment") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Reservation) MarshalJSON() ([]byte, error) {
	type NoMethod Reservation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReservationAffinity: Specifies the reservations that this instance
// can consume from.
type ReservationAffinity struct {
	// ConsumeReservationType: Specifies the type of reservation from which
	// this instance can consume resources: ANY_RESERVATION (default),
	// SPECIFIC_RESERVATION, or NO_RESERVATION. See  Consuming reserved
	// instances for examples.
	//
	// Possible values:
	//   "ANY_RESERVATION"
	//   "NO_RESERVATION"
	//   "SPECIFIC_RESERVATION"
	//   "UNSPECIFIED"
	ConsumeReservationType string `json:"consumeReservationType,omitempty"`

	// Key: Corresponds to the label key of a reservation resource. To
	// target a SPECIFIC_RESERVATION by name, specify
	// googleapis.com/reservation-name as the key and specify the name of
	// your reservation as its value.
	Key string `json:"key,omitempty"`

	// Values: Corresponds to the label values of a reservation resource.
	Values []string `json:"values,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ConsumeReservationType") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ConsumeReservationType")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReservationAffinity) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationAffinity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReservationAggregatedList: Contains a list of reservations.
type ReservationAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Allocation resources.
	Items map[string]ReservationsScopedList `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ReservationAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReservationAggregatedListWarning: [Output Only] Informational warning
// message.
type ReservationAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ReservationAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ReservationAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ReservationList struct {
	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id string `json:"id,omitempty"`

	// Items: [Output Only] A list of Allocation resources.
	Items []*Reservation `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always compute#reservationsList
	// for listsof reservations
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ReservationListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationList) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReservationListWarning: [Output Only] Informational warning message.
type ReservationListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ReservationListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ReservationListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ReservationsResizeRequest struct {
	// SpecificSkuCount: Number of allocated resources can be resized with
	// minimum = 1 and maximum = 1000.
	SpecificSkuCount int64 `json:"specificSkuCount,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "SpecificSkuCount") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SpecificSkuCount") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReservationsResizeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationsResizeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ReservationsScopedList struct {
	// Reservations: A list of reservations contained in this scope.
	Reservations []*Reservation `json:"reservations,omitempty"`

	// Warning: Informational warning which replaces the list of
	// reservations when the list is empty.
	Warning *ReservationsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Reservations") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Reservations") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReservationsScopedListWarning: Informational warning which replaces
// the list of reservations when the list is empty.
type ReservationsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ReservationsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ReservationsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReservationsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ReservationsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourceCommitment: Commitment for a particular resource (a
// Commitment is composed of one or more of these).
type ResourceCommitment struct {
	// AcceleratorType: Name of the accelerator type resource. Applicable
	// only when the type is ACCELERATOR.
	AcceleratorType string `json:"acceleratorType,omitempty"`

	// Amount: The amount of the resource purchased (in a type-dependent
	// unit, such as bytes). For vCPUs, this can just be an integer. For
	// memory, this must be provided in MB. Memory must be a multiple of 256
	// MB, with up to 6.5GB of memory per every vCPU.
	Amount int64 `json:"amount,omitempty,string"`

	// Type: Type of resource for which this commitment applies. Possible
	// values are VCPU and MEMORY
	//
	// Possible values:
	//   "ACCELERATOR"
	//   "LOCAL_SSD"
	//   "MEMORY"
	//   "UNSPECIFIED"
	//   "VCPU"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AcceleratorType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AcceleratorType") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ResourceCommitment) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceCommitment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourceGroupReference struct {
	// Group: A URI referencing one of the instance groups or network
	// endpoint groups listed in the backend service.
	Group string `json:"group,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Group") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Group") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourceGroupReference) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceGroupReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourcePoliciesScopedList struct {
	// ResourcePolicies: A list of resourcePolicies contained in this scope.
	ResourcePolicies []*ResourcePolicy `json:"resourcePolicies,omitempty"`

	// Warning: Informational warning which replaces the list of
	// resourcePolicies when the list is empty.
	Warning *ResourcePoliciesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourcePolicies") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ResourcePolicies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePoliciesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePoliciesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePoliciesScopedListWarning: Informational warning which
// replaces the list of resourcePolicies when the list is empty.
type ResourcePoliciesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ResourcePoliciesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePoliciesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePoliciesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourcePoliciesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePoliciesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePoliciesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourcePolicy struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#resource_policies for resource policies.
	Kind string `json:"kind,omitempty"`

	// Name: The name of the resource, provided by the client when initially
	// creating the resource. The resource name must be 1-63 characters
	// long, and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined fully-qualified URL for this
	// resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SnapshotSchedulePolicy: Resource policy for persistent disks for
	// creating snapshots.
	SnapshotSchedulePolicy *ResourcePolicySnapshotSchedulePolicy `json:"snapshotSchedulePolicy,omitempty"`

	// Status: [Output Only] The status of resource policy creation.
	//
	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "INVALID"
	//   "READY"
	Status string `json:"status,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicy) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicyAggregatedList: Contains a list of resourcePolicies.
type ResourcePolicyAggregatedList struct {
	Etag string `json:"etag,omitempty"`

	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of ResourcePolicy resources.
	Items map[string]ResourcePoliciesScopedList `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ResourcePolicyAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Etag") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicyAggregatedListWarning: [Output Only] Informational
// warning message.
type ResourcePolicyAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ResourcePolicyAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourcePolicyAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicyDailyCycle: Time window specified for daily operations.
type ResourcePolicyDailyCycle struct {
	// DaysInCycle: Defines a schedule that runs every nth day of the month.
	DaysInCycle int64 `json:"daysInCycle,omitempty"`

	// Duration: [Output only] A predetermined duration for the window,
	// automatically chosen to be the smallest possible in the given
	// scenario.
	Duration string `json:"duration,omitempty"`

	// StartTime: Start time of the window. This must be in UTC format that
	// resolves to one of 00:00, 04:00, 08:00, 12:00, 16:00, or 20:00. For
	// example, both 13:00-5 and 08:00 are valid.
	StartTime string `json:"startTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DaysInCycle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DaysInCycle") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyDailyCycle) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyDailyCycle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicyHourlyCycle: Time window specified for hourly
// operations.
type ResourcePolicyHourlyCycle struct {
	// Duration: [Output only] Duration of the time window, automatically
	// chosen to be smallest possible in the given scenario.
	Duration string `json:"duration,omitempty"`

	// HoursInCycle: Allows to define schedule that runs every nth hour.
	HoursInCycle int64 `json:"hoursInCycle,omitempty"`

	// StartTime: Time within the window to start the operations. It must be
	// in format "HH:MM", where HH : [00-23] and MM : [00-00] GMT.
	StartTime string `json:"startTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Duration") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Duration") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyHourlyCycle) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyHourlyCycle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourcePolicyList struct {
	Etag string `json:"etag,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id string `json:"id,omitempty"`

	// Items: [Output Only] A list of ResourcePolicy resources.
	Items []*ResourcePolicy `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource.Always
	// compute#resourcePoliciesList for listsof resourcePolicies
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ResourcePolicyListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Etag") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyList) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicyListWarning: [Output Only] Informational warning
// message.
type ResourcePolicyListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ResourcePolicyListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourcePolicyListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicySnapshotSchedulePolicy: A snapshot schedule policy
// specifies when and how frequently snapshots are to be created for the
// target disk. Also specifies how many and how long these scheduled
// snapshots should be retained.
type ResourcePolicySnapshotSchedulePolicy struct {
	// RetentionPolicy: Retention policy applied to snapshots created by
	// this resource policy.
	RetentionPolicy *ResourcePolicySnapshotSchedulePolicyRetentionPolicy `json:"retentionPolicy,omitempty"`

	// Schedule: A Vm Maintenance Policy specifies what kind of
	// infrastructure maintenance we are allowed to perform on this VM and
	// when. Schedule that is applied to disks covered by this policy.
	Schedule *ResourcePolicySnapshotSchedulePolicySchedule `json:"schedule,omitempty"`

	// SnapshotProperties: Properties with which snapshots are created such
	// as labels, encryption keys.
	SnapshotProperties *ResourcePolicySnapshotSchedulePolicySnapshotProperties `json:"snapshotProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RetentionPolicy") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RetentionPolicy") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicySnapshotSchedulePolicy) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicySnapshotSchedulePolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicySnapshotSchedulePolicyRetentionPolicy: Policy for
// retention of scheduled snapshots.
type ResourcePolicySnapshotSchedulePolicyRetentionPolicy struct {
	// MaxRetentionDays: Maximum age of the snapshot that is allowed to be
	// kept.
	MaxRetentionDays int64 `json:"maxRetentionDays,omitempty"`

	// OnSourceDiskDelete: Specifies the behavior to apply to scheduled
	// snapshots when the source disk is deleted.
	//
	// Possible values:
	//   "APPLY_RETENTION_POLICY"
	//   "KEEP_AUTO_SNAPSHOTS"
	//   "UNSPECIFIED_ON_SOURCE_DISK_DELETE"
	OnSourceDiskDelete string `json:"onSourceDiskDelete,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MaxRetentionDays") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MaxRetentionDays") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicySnapshotSchedulePolicyRetentionPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicySnapshotSchedulePolicyRetentionPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicySnapshotSchedulePolicySchedule: A schedule for disks
// where the schedueled operations are performed.
type ResourcePolicySnapshotSchedulePolicySchedule struct {
	DailySchedule *ResourcePolicyDailyCycle `json:"dailySchedule,omitempty"`

	HourlySchedule *ResourcePolicyHourlyCycle `json:"hourlySchedule,omitempty"`

	WeeklySchedule *ResourcePolicyWeeklyCycle `json:"weeklySchedule,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DailySchedule") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DailySchedule") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicySnapshotSchedulePolicySchedule) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicySnapshotSchedulePolicySchedule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicySnapshotSchedulePolicySnapshotProperties: Specified
// snapshot properties for scheduled snapshots created by this policy.
type ResourcePolicySnapshotSchedulePolicySnapshotProperties struct {
	// GuestFlush: Indication to perform a ?guest aware? snapshot.
	GuestFlush bool `json:"guestFlush,omitempty"`

	// Labels: Labels to apply to scheduled snapshots. These can be later
	// modified by the setLabels method. Label values may be empty.
	Labels map[string]string `json:"labels,omitempty"`

	// StorageLocations: Cloud Storage bucket storage location of the auto
	// snapshot (regional or multi-regional).
	StorageLocations []string `json:"storageLocations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GuestFlush") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GuestFlush") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicySnapshotSchedulePolicySnapshotProperties) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicySnapshotSchedulePolicySnapshotProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourcePolicyWeeklyCycle: Time window specified for weekly
// operations.
type ResourcePolicyWeeklyCycle struct {
	// DayOfWeeks: Up to 7 intervals/windows, one for each day of the week.
	DayOfWeeks []*ResourcePolicyWeeklyCycleDayOfWeek `json:"dayOfWeeks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DayOfWeeks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DayOfWeeks") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyWeeklyCycle) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyWeeklyCycle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ResourcePolicyWeeklyCycleDayOfWeek struct {
	// Day: Allows to define schedule that runs specified day of the week.
	//
	// Possible values:
	//   "FRIDAY"
	//   "INVALID"
	//   "MONDAY"
	//   "SATURDAY"
	//   "SUNDAY"
	//   "THURSDAY"
	//   "TUESDAY"
	//   "WEDNESDAY"
	Day string `json:"day,omitempty"`

	// Duration: [Output only] Duration of the time window, automatically
	// chosen to be smallest possible in the given scenario.
	Duration string `json:"duration,omitempty"`

	// StartTime: Time within the window to start the operations. It must be
	// in format "HH:MM", where HH : [00-23] and MM : [00-00] GMT.
	StartTime string `json:"startTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Day") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Day") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ResourcePolicyWeeklyCycleDayOfWeek) MarshalJSON() ([]byte, error) {
	type NoMethod ResourcePolicyWeeklyCycleDayOfWeek
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Route: Represents a Route resource.
//
// A route defines a path from VM instances in the VPC network to a
// specific destination. This destination can be inside or outside the
// VPC network. For more information, read the Routes overview. (==
// resource_for beta.routes ==) (== resource_for v1.routes ==)
type Route struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// field when you create the resource.
	Description string `json:"description,omitempty"`

	// DestRange: The destination range of outgoing packets that this route
	// applies to. Only IPv4 is supported.
	DestRange string `json:"destRange,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of this resource. Always compute#routes for
	// Route resources.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?`. The first
	// character must be a lowercase letter, and all following characters
	// (except for the last character) must be a dash, lowercase letter, or
	// digit. The last character must be a lowercase letter or digit.
	Name string `json:"name,omitempty"`

	// Network: Fully-qualified URL of the network that this route applies
	// to.
	Network string `json:"network,omitempty"`

	// NextHopGateway: The URL to a gateway that should handle matching
	// packets. You can only specify the internet gateway using a full or
	// partial valid URL:
	// projects/project/global/gateways/default-internet-gateway
	NextHopGateway string `json:"nextHopGateway,omitempty"`

	// NextHopIlb: The URL to a forwarding rule of type
	// loadBalancingScheme=INTERNAL that should handle matching packets. You
	// can only specify the forwarding rule as a partial or full URL. For
	// example, the following are all valid URLs:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/regions/region/forwardingRules/forwardingRule
	// - regions/region/forwardingRules/forwardingRule
	NextHopIlb string `json:"nextHopIlb,omitempty"`

	// NextHopInstance: The URL to an instance that should handle matching
	// packets. You can specify this as a full or partial URL. For
	// example:
	// https://www.googleapis.com/compute/v1/projects/project/zones/
	// zone/instances/
	NextHopInstance string `json:"nextHopInstance,omitempty"`

	// NextHopIp: The network IP address of an instance that should handle
	// matching packets. Only IPv4 is supported.
	NextHopIp string `json:"nextHopIp,omitempty"`

	// NextHopNetwork: The URL of the local network if it should handle
	// matching packets.
	NextHopNetwork string `json:"nextHopNetwork,omitempty"`

	// NextHopPeering: [Output Only] The network peering name that should
	// handle matching packets, which should conform to RFC1035.
	NextHopPeering string `json:"nextHopPeering,omitempty"`

	// NextHopVpnTunnel: The URL to a VpnTunnel that should handle matching
	// packets.
	NextHopVpnTunnel string `json:"nextHopVpnTunnel,omitempty"`

	// Priority: The priority of this route. Priority is used to break ties
	// in cases where there is more than one matching route of equal prefix
	// length. In cases where multiple routes have equal prefix length, the
	// one with the lowest-numbered priority value wins. The default value
	// is `1000`. The priority value must be from `0` to `65535`, inclusive.
	Priority int64 `json:"priority,omitempty"`

	// SelfLink: [Output Only] Server-defined fully-qualified URL for this
	// resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Tags: A list of instance tags to which this route applies.
	Tags []string `json:"tags,omitempty"`

	// Warnings: [Output Only] If potential misconfigurations are detected
	// for this route, this field will be populated with warning messages.
	Warnings []*RouteWarnings `json:"warnings,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Route) MarshalJSON() ([]byte, error) {
	type NoMethod Route
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouteWarnings struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RouteWarningsData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouteWarnings) MarshalJSON() ([]byte, error) {
	type NoMethod RouteWarnings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouteWarningsData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouteWarningsData) MarshalJSON() ([]byte, error) {
	type NoMethod RouteWarningsData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouteList: Contains a list of Route resources.
type RouteList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Route resources.
	Items []*Route `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RouteListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouteList) MarshalJSON() ([]byte, error) {
	type NoMethod RouteList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouteListWarning: [Output Only] Informational warning message.
type RouteListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RouteListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouteListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RouteListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouteListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouteListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RouteListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Router: Represents a Cloud Router resource.
//
// For more information about Cloud Router, read the the Cloud Router
// overview.
type Router struct {
	// Bgp: BGP information specific to this router.
	Bgp *RouterBgp `json:"bgp,omitempty"`

	// BgpPeers: BGP information that must be configured into the routing
	// stack to establish BGP peering. This information must specify the
	// peer ASN and either the interface name, IP address, or peer IP
	// address. Please refer to RFC4273.
	BgpPeers []*RouterBgpPeer `json:"bgpPeers,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Interfaces: Router interfaces. Each interface requires either one
	// linked resource, (for example, linkedVpnTunnel), or IP address and IP
	// address range (for example, ipRange), or both.
	Interfaces []*RouterInterface `json:"interfaces,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#router for
	// routers.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Nats: A list of NAT services created in this router.
	Nats []*RouterNat `json:"nats,omitempty"`

	// Network: URI of the network to which this router belongs.
	Network string `json:"network,omitempty"`

	// Region: [Output Only] URI of the region where the router resides. You
	// must specify this field as part of the HTTP request URL. It is not
	// settable as a field in the request body.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Bgp") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bgp") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Router) MarshalJSON() ([]byte, error) {
	type NoMethod Router
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterAdvertisedIpRange: Description-tagged IP ranges for the router
// to advertise.
type RouterAdvertisedIpRange struct {
	// Description: User-specified description for the IP range.
	Description string `json:"description,omitempty"`

	// Range: The IP range to advertise. The value must be a CIDR-formatted
	// string.
	Range string `json:"range,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterAdvertisedIpRange) MarshalJSON() ([]byte, error) {
	type NoMethod RouterAdvertisedIpRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterAggregatedList: Contains a list of routers.
type RouterAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Router resources.
	Items map[string]RoutersScopedList `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RouterAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod RouterAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterAggregatedListWarning: [Output Only] Informational warning
// message.
type RouterAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RouterAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RouterAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RouterAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterBgp struct {
	// AdvertiseMode: User-specified flag to indicate which mode to use for
	// advertisement. The options are DEFAULT or CUSTOM.
	//
	// Possible values:
	//   "CUSTOM"
	//   "DEFAULT"
	AdvertiseMode string `json:"advertiseMode,omitempty"`

	// AdvertisedGroups: User-specified list of prefix groups to advertise
	// in custom mode. This field can only be populated if advertise_mode is
	// CUSTOM and is advertised to all peers of the router. These groups
	// will be advertised in addition to any specified prefixes. Leave this
	// field blank to advertise no custom groups.
	//
	// Possible values:
	//   "ALL_SUBNETS"
	AdvertisedGroups []string `json:"advertisedGroups,omitempty"`

	// AdvertisedIpRanges: User-specified list of individual IP ranges to
	// advertise in custom mode. This field can only be populated if
	// advertise_mode is CUSTOM and is advertised to all peers of the
	// router. These IP ranges will be advertised in addition to any
	// specified groups. Leave this field blank to advertise no custom IP
	// ranges.
	AdvertisedIpRanges []*RouterAdvertisedIpRange `json:"advertisedIpRanges,omitempty"`

	// Asn: Local BGP Autonomous System Number (ASN). Must be an RFC6996
	// private ASN, either 16-bit or 32-bit. The value will be fixed for
	// this router resource. All VPN tunnels that link to this router will
	// have the same local ASN.
	Asn int64 `json:"asn,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdvertiseMode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdvertiseMode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterBgp) MarshalJSON() ([]byte, error) {
	type NoMethod RouterBgp
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterBgpPeer struct {
	// AdvertiseMode: User-specified flag to indicate which mode to use for
	// advertisement.
	//
	// Possible values:
	//   "CUSTOM"
	//   "DEFAULT"
	AdvertiseMode string `json:"advertiseMode,omitempty"`

	// AdvertisedGroups: User-specified list of prefix groups to advertise
	// in custom mode, which can take one of the following options:
	// - ALL_SUBNETS: Advertises all available subnets, including peer VPC
	// subnets.
	// - ALL_VPC_SUBNETS: Advertises the router's own VPC subnets.
	// - ALL_PEER_VPC_SUBNETS: Advertises peer subnets of the router's VPC
	// network. Note that this field can only be populated if advertise_mode
	// is CUSTOM and overrides the list defined for the router (in the "bgp"
	// message). These groups are advertised in addition to any specified
	// prefixes. Leave this field blank to advertise no custom groups.
	//
	// Possible values:
	//   "ALL_SUBNETS"
	AdvertisedGroups []string `json:"advertisedGroups,omitempty"`

	// AdvertisedIpRanges: User-specified list of individual IP ranges to
	// advertise in custom mode. This field can only be populated if
	// advertise_mode is CUSTOM and overrides the list defined for the
	// router (in the "bgp" message). These IP ranges are advertised in
	// addition to any specified groups. Leave this field blank to advertise
	// no custom IP ranges.
	AdvertisedIpRanges []*RouterAdvertisedIpRange `json:"advertisedIpRanges,omitempty"`

	// AdvertisedRoutePriority: The priority of routes advertised to this
	// BGP peer. Where there is more than one matching route of maximum
	// length, the routes with the lowest priority value win.
	AdvertisedRoutePriority int64 `json:"advertisedRoutePriority,omitempty"`

	// InterfaceName: Name of the interface the BGP peer is associated with.
	InterfaceName string `json:"interfaceName,omitempty"`

	// IpAddress: IP address of the interface inside Google Cloud Platform.
	// Only IPv4 is supported.
	IpAddress string `json:"ipAddress,omitempty"`

	// ManagementType: [Output Only] The resource that configures and
	// manages this BGP peer.
	// - MANAGED_BY_USER is the default value and can be managed by you or
	// other users
	// - MANAGED_BY_ATTACHMENT is a BGP peer that is configured and managed
	// by Cloud Interconnect, specifically by an InterconnectAttachment of
	// type PARTNER. Google automatically creates, updates, and deletes this
	// type of BGP peer when the PARTNER InterconnectAttachment is created,
	// updated, or deleted.
	//
	// Possible values:
	//   "MANAGED_BY_ATTACHMENT"
	//   "MANAGED_BY_USER"
	ManagementType string `json:"managementType,omitempty"`

	// Name: Name of this BGP peer. The name must be 1-63 characters long,
	// and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	// PeerAsn: Peer BGP Autonomous System Number (ASN). Each BGP interface
	// may use a different value.
	PeerAsn int64 `json:"peerAsn,omitempty"`

	// PeerIpAddress: IP address of the BGP interface outside Google Cloud
	// Platform. Only IPv4 is supported.
	PeerIpAddress string `json:"peerIpAddress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdvertiseMode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdvertiseMode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterBgpPeer) MarshalJSON() ([]byte, error) {
	type NoMethod RouterBgpPeer
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterInterface struct {
	// IpRange: IP address and range of the interface. The IP range must be
	// in the RFC3927 link-local IP address space. The value must be a
	// CIDR-formatted string, for example: 169.254.0.1/30. NOTE: Do not
	// truncate the address as it represents the IP address of the
	// interface.
	IpRange string `json:"ipRange,omitempty"`

	// LinkedInterconnectAttachment: URI of the linked Interconnect
	// attachment. It must be in the same region as the router. Each
	// interface can have one linked resource, which can be either be a VPN
	// tunnel or an Interconnect attachment.
	LinkedInterconnectAttachment string `json:"linkedInterconnectAttachment,omitempty"`

	// LinkedVpnTunnel: URI of the linked VPN tunnel, which must be in the
	// same region as the router. Each interface can have one linked
	// resource, which can be either a VPN tunnel or an Interconnect
	// attachment.
	LinkedVpnTunnel string `json:"linkedVpnTunnel,omitempty"`

	// ManagementType: [Output Only] The resource that configures and
	// manages this interface.
	// - MANAGED_BY_USER is the default value and can be managed directly by
	// users.
	// - MANAGED_BY_ATTACHMENT is an interface that is configured and
	// managed by Cloud Interconnect, specifically, by an
	// InterconnectAttachment of type PARTNER. Google automatically creates,
	// updates, and deletes this type of interface when the PARTNER
	// InterconnectAttachment is created, updated, or deleted.
	//
	// Possible values:
	//   "MANAGED_BY_ATTACHMENT"
	//   "MANAGED_BY_USER"
	ManagementType string `json:"managementType,omitempty"`

	// Name: Name of this interface entry. The name must be 1-63 characters
	// long, and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpRange") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterInterface) MarshalJSON() ([]byte, error) {
	type NoMethod RouterInterface
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterList: Contains a list of Router resources.
type RouterList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Router resources.
	Items []*Router `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#router for
	// routers.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *RouterListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterList) MarshalJSON() ([]byte, error) {
	type NoMethod RouterList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterListWarning: [Output Only] Informational warning message.
type RouterListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RouterListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RouterListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RouterListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterNat: Represents a Nat resource. It enables the VMs within the
// specified subnetworks to access Internet without external IP
// addresses. It specifies a list of subnetworks (and the ranges within)
// that want to use NAT. Customers can also provide the external IPs
// that would be used for NAT. GCP would auto-allocate ephemeral IPs if
// no external IPs are provided.
type RouterNat struct {
	// DrainNatIps: A list of URLs of the IP resources to be drained. These
	// IPs must be valid static external IPs that have been assigned to the
	// NAT. These IPs should be used for updating/patching a NAT only.
	DrainNatIps []string `json:"drainNatIps,omitempty"`

	// IcmpIdleTimeoutSec: Timeout (in seconds) for ICMP connections.
	// Defaults to 30s if not set.
	IcmpIdleTimeoutSec int64 `json:"icmpIdleTimeoutSec,omitempty"`

	// LogConfig: Configure logging on this NAT.
	LogConfig *RouterNatLogConfig `json:"logConfig,omitempty"`

	// MinPortsPerVm: Minimum number of ports allocated to a VM from this
	// NAT config. If not set, a default number of ports is allocated to a
	// VM. This is rounded up to the nearest power of 2. For example, if the
	// value of this field is 50, at least 64 ports are allocated to a VM.
	MinPortsPerVm int64 `json:"minPortsPerVm,omitempty"`

	// Name: Unique name of this Nat service. The name must be 1-63
	// characters long and comply with RFC1035.
	Name string `json:"name,omitempty"`

	// NatIpAllocateOption: Specify the NatIpAllocateOption, which can take
	// one of the following values:
	// - MANUAL_ONLY: Uses only Nat IP addresses provided by customers. When
	// there are not enough specified Nat IPs, the Nat service fails for new
	// VMs.
	// - AUTO_ONLY: Nat IPs are allocated by Google Cloud Platform;
	// customers can't specify any Nat IPs. When choosing AUTO_ONLY, then
	// nat_ip should be empty.
	//
	// Possible values:
	//   "AUTO_ONLY"
	//   "MANUAL_ONLY"
	NatIpAllocateOption string `json:"natIpAllocateOption,omitempty"`

	// NatIps: A list of URLs of the IP resources used for this Nat service.
	// These IP addresses must be valid static external IP addresses
	// assigned to the project.
	NatIps []string `json:"natIps,omitempty"`

	// SourceSubnetworkIpRangesToNat: Specify the Nat option, which can take
	// one of the following values:
	// - ALL_SUBNETWORKS_ALL_IP_RANGES: All of the IP ranges in every
	// Subnetwork are allowed to Nat.
	// - ALL_SUBNETWORKS_ALL_PRIMARY_IP_RANGES: All of the primary IP ranges
	// in every Subnetwork are allowed to Nat.
	// - LIST_OF_SUBNETWORKS: A list of Subnetworks are allowed to Nat
	// (specified in the field subnetwork below) The default is
	// SUBNETWORK_IP_RANGE_TO_NAT_OPTION_UNSPECIFIED. Note that if this
	// field contains ALL_SUBNETWORKS_ALL_IP_RANGES or
	// ALL_SUBNETWORKS_ALL_PRIMARY_IP_RANGES, then there should not be any
	// other Router.Nat section in any Router for this network in this
	// region.
	//
	// Possible values:
	//   "ALL_SUBNETWORKS_ALL_IP_RANGES"
	//   "ALL_SUBNETWORKS_ALL_PRIMARY_IP_RANGES"
	//   "LIST_OF_SUBNETWORKS"
	SourceSubnetworkIpRangesToNat string `json:"sourceSubnetworkIpRangesToNat,omitempty"`

	// Subnetworks: A list of Subnetwork resources whose traffic should be
	// translated by NAT Gateway. It is used only when LIST_OF_SUBNETWORKS
	// is selected for the SubnetworkIpRangeToNatOption above.
	Subnetworks []*RouterNatSubnetworkToNat `json:"subnetworks,omitempty"`

	// TcpEstablishedIdleTimeoutSec: Timeout (in seconds) for TCP
	// established connections. Defaults to 1200s if not set.
	TcpEstablishedIdleTimeoutSec int64 `json:"tcpEstablishedIdleTimeoutSec,omitempty"`

	// TcpTransitoryIdleTimeoutSec: Timeout (in seconds) for TCP transitory
	// connections. Defaults to 30s if not set.
	TcpTransitoryIdleTimeoutSec int64 `json:"tcpTransitoryIdleTimeoutSec,omitempty"`

	// UdpIdleTimeoutSec: Timeout (in seconds) for UDP connections. Defaults
	// to 30s if not set.
	UdpIdleTimeoutSec int64 `json:"udpIdleTimeoutSec,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DrainNatIps") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DrainNatIps") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterNat) MarshalJSON() ([]byte, error) {
	type NoMethod RouterNat
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterNatLogConfig: Configuration of logging on a NAT.
type RouterNatLogConfig struct {
	// Enable: Indicates whether or not to export logs. This is false by
	// default.
	Enable bool `json:"enable,omitempty"`

	// Filter: Specify the desired filtering of logs on this NAT. If
	// unspecified, logs are exported for all connections handled by this
	// NAT. This option can take one of the following values:
	// - ERRORS_ONLY: Export logs only for connection failures.
	// - TRANSLATIONS_ONLY: Export logs only for successful connections.
	// - ALL: Export logs for all connections, successful and unsuccessful.
	//
	// Possible values:
	//   "ALL"
	//   "ERRORS_ONLY"
	//   "TRANSLATIONS_ONLY"
	Filter string `json:"filter,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Enable") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Enable") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterNatLogConfig) MarshalJSON() ([]byte, error) {
	type NoMethod RouterNatLogConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterNatSubnetworkToNat: Defines the IP ranges that want to use NAT
// for a subnetwork.
type RouterNatSubnetworkToNat struct {
	// Name: URL for the subnetwork resource that will use NAT.
	Name string `json:"name,omitempty"`

	// SecondaryIpRangeNames: A list of the secondary ranges of the
	// Subnetwork that are allowed to use NAT. This can be populated only if
	// "LIST_OF_SECONDARY_IP_RANGES" is one of the values in
	// source_ip_ranges_to_nat.
	SecondaryIpRangeNames []string `json:"secondaryIpRangeNames,omitempty"`

	// SourceIpRangesToNat: Specify the options for NAT ranges in the
	// Subnetwork. All options of a single value are valid except
	// NAT_IP_RANGE_OPTION_UNSPECIFIED. The only valid option with multiple
	// values is: ["PRIMARY_IP_RANGE", "LIST_OF_SECONDARY_IP_RANGES"]
	// Default: [ALL_IP_RANGES]
	//
	// Possible values:
	//   "ALL_IP_RANGES"
	//   "LIST_OF_SECONDARY_IP_RANGES"
	//   "PRIMARY_IP_RANGE"
	SourceIpRangesToNat []string `json:"sourceIpRangesToNat,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterNatSubnetworkToNat) MarshalJSON() ([]byte, error) {
	type NoMethod RouterNatSubnetworkToNat
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterStatus struct {
	// BestRoutes: Best routes for this router's network.
	BestRoutes []*Route `json:"bestRoutes,omitempty"`

	// BestRoutesForRouter: Best routes learned by this router.
	BestRoutesForRouter []*Route `json:"bestRoutesForRouter,omitempty"`

	BgpPeerStatus []*RouterStatusBgpPeerStatus `json:"bgpPeerStatus,omitempty"`

	NatStatus []*RouterStatusNatStatus `json:"natStatus,omitempty"`

	// Network: URI of the network to which this router belongs.
	Network string `json:"network,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BestRoutes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BestRoutes") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterStatus) MarshalJSON() ([]byte, error) {
	type NoMethod RouterStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterStatusBgpPeerStatus struct {
	// AdvertisedRoutes: Routes that were advertised to the remote BGP peer
	AdvertisedRoutes []*Route `json:"advertisedRoutes,omitempty"`

	// IpAddress: IP address of the local BGP interface.
	IpAddress string `json:"ipAddress,omitempty"`

	// LinkedVpnTunnel: URL of the VPN tunnel that this BGP peer controls.
	LinkedVpnTunnel string `json:"linkedVpnTunnel,omitempty"`

	// Name: Name of this BGP peer. Unique within the Routers resource.
	Name string `json:"name,omitempty"`

	// NumLearnedRoutes: Number of routes learned from the remote BGP Peer.
	NumLearnedRoutes int64 `json:"numLearnedRoutes,omitempty"`

	// PeerIpAddress: IP address of the remote BGP interface.
	PeerIpAddress string `json:"peerIpAddress,omitempty"`

	// State: BGP state as specified in RFC1771.
	State string `json:"state,omitempty"`

	// Status: Status of the BGP peer: {UP, DOWN}
	//
	// Possible values:
	//   "DOWN"
	//   "UNKNOWN"
	//   "UP"
	Status string `json:"status,omitempty"`

	// Uptime: Time this session has been up. Format: 14 years, 51 weeks, 6
	// days, 23 hours, 59 minutes, 59 seconds
	Uptime string `json:"uptime,omitempty"`

	// UptimeSeconds: Time this session has been up, in seconds. Format: 145
	UptimeSeconds string `json:"uptimeSeconds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdvertisedRoutes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdvertisedRoutes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RouterStatusBgpPeerStatus) MarshalJSON() ([]byte, error) {
	type NoMethod RouterStatusBgpPeerStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RouterStatusNatStatus: Status of a NAT contained in this router. Next
// tag: 9
type RouterStatusNatStatus struct {
	// AutoAllocatedNatIps: A list of IPs auto-allocated for NAT. Example:
	// ["1.1.1.1", "129.2.16.89"]
	AutoAllocatedNatIps []string `json:"autoAllocatedNatIps,omitempty"`

	// DrainAutoAllocatedNatIps: A list of IPs auto-allocated for NAT that
	// are in drain mode. Example: ["1.1.1.1", "179.12.26.133"].
	DrainAutoAllocatedNatIps []string `json:"drainAutoAllocatedNatIps,omitempty"`

	// DrainUserAllocatedNatIps: A list of IPs user-allocated for NAT that
	// are in drain mode. Example: ["1.1.1.1", "179.12.26.133"].
	DrainUserAllocatedNatIps []string `json:"drainUserAllocatedNatIps,omitempty"`

	// MinExtraNatIpsNeeded: The number of extra IPs to allocate. This will
	// be greater than 0 only if user-specified IPs are NOT enough to allow
	// all configured VMs to use NAT. This value is meaningful only when
	// auto-allocation of NAT IPs is *not* used.
	MinExtraNatIpsNeeded int64 `json:"minExtraNatIpsNeeded,omitempty"`

	// Name: Unique name of this NAT.
	Name string `json:"name,omitempty"`

	// NumVmEndpointsWithNatMappings: Number of VM endpoints (i.e., Nics)
	// that can use NAT.
	NumVmEndpointsWithNatMappings int64 `json:"numVmEndpointsWithNatMappings,omitempty"`

	// UserAllocatedNatIpResources: A list of fully qualified URLs of
	// reserved IP address resources.
	UserAllocatedNatIpResources []string `json:"userAllocatedNatIpResources,omitempty"`

	// UserAllocatedNatIps: A list of IPs user-allocated for NAT. They will
	// be raw IP strings like "179.12.26.133".
	UserAllocatedNatIps []string `json:"userAllocatedNatIps,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoAllocatedNatIps")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoAllocatedNatIps") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RouterStatusNatStatus) MarshalJSON() ([]byte, error) {
	type NoMethod RouterStatusNatStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RouterStatusResponse struct {
	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	Result *RouterStatus `json:"result,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RouterStatusResponse) MarshalJSON() ([]byte, error) {
	type NoMethod RouterStatusResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RoutersPreviewResponse struct {
	// Resource: Preview of given router.
	Resource *Router `json:"resource,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Resource") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Resource") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RoutersPreviewResponse) MarshalJSON() ([]byte, error) {
	type NoMethod RoutersPreviewResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RoutersScopedList struct {
	// Routers: A list of routers contained in this scope.
	Routers []*Router `json:"routers,omitempty"`

	// Warning: Informational warning which replaces the list of routers
	// when the list is empty.
	Warning *RoutersScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Routers") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Routers") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RoutersScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod RoutersScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RoutersScopedListWarning: Informational warning which replaces the
// list of routers when the list is empty.
type RoutersScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*RoutersScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RoutersScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod RoutersScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RoutersScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RoutersScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod RoutersScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Rule: A rule to be applied in a Policy.
type Rule struct {
	// Action: Required
	//
	// Possible values:
	//   "ALLOW"
	//   "ALLOW_WITH_LOG"
	//   "DENY"
	//   "DENY_WITH_LOG"
	//   "LOG"
	//   "NO_ACTION"
	Action string `json:"action,omitempty"`

	// Conditions: Additional restrictions that must be met. All conditions
	// must pass for the rule to match.
	Conditions []*Condition `json:"conditions,omitempty"`

	// Description: Human-readable description of the rule.
	Description string `json:"description,omitempty"`

	// Ins: If one or more 'in' clauses are specified, the rule matches if
	// the PRINCIPAL/AUTHORITY_SELECTOR is in at least one of these entries.
	Ins []string `json:"ins,omitempty"`

	// LogConfigs: The config returned to callers of
	// tech.iam.IAM.CheckPolicy for any entries that match the LOG action.
	LogConfigs []*LogConfig `json:"logConfigs,omitempty"`

	// NotIns: If one or more 'not_in' clauses are specified, the rule
	// matches if the PRINCIPAL/AUTHORITY_SELECTOR is in none of the
	// entries.
	NotIns []string `json:"notIns,omitempty"`

	// Permissions: A permission is a string of form '..' (e.g.,
	// 'storage.buckets.list'). A value of '*' matches all permissions, and
	// a verb part of '*' (e.g., 'storage.buckets.*') matches all verbs.
	Permissions []string `json:"permissions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Action") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Action") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Rule) MarshalJSON() ([]byte, error) {
	type NoMethod Rule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SSLHealthCheck struct {
	// Port: The TCP port number for the health check request. The default
	// value is 443. Valid values are 1 through 65535.
	Port int64 `json:"port,omitempty"`

	// PortName: Port name as defined in InstanceGroup#NamedPort#name. If
	// both port and port_name are defined, port takes precedence.
	PortName string `json:"portName,omitempty"`

	// PortSpecification: Specifies how port is selected for health
	// checking, can be one of following values:
	// USE_FIXED_PORT: The port number in
	// port
	// is used for health checking.
	// USE_NAMED_PORT: The
	// portName
	// is used for health checking.
	// USE_SERVING_PORT: For NetworkEndpointGroup, the port specified for
	// each network endpoint is used for health checking. For other
	// backends, the port or named port specified in the Backend Service is
	// used for health checking.
	//
	//
	// If not specified, SSL health check follows behavior specified
	// in
	// port
	// and
	// portName
	// fields.
	//
	// Possible values:
	//   "USE_FIXED_PORT"
	//   "USE_NAMED_PORT"
	//   "USE_SERVING_PORT"
	PortSpecification string `json:"portSpecification,omitempty"`

	// ProxyHeader: Specifies the type of proxy header to append before
	// sending data to the backend, either NONE or PROXY_V1. The default is
	// NONE.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// Request: The application data to send once the SSL connection has
	// been established (default value is empty). If both request and
	// response are empty, the connection establishment alone will indicate
	// health. The request data can only be ASCII.
	Request string `json:"request,omitempty"`

	// Response: The bytes to match against the beginning of the response
	// data. If left empty (the default value), any response will indicate
	// health. The response data can only be ASCII.
	Response string `json:"response,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Port") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Port") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SSLHealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod SSLHealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Scheduling: Sets the scheduling options for an Instance. NextID: 9
type Scheduling struct {
	// AutomaticRestart: Specifies whether the instance should be
	// automatically restarted if it is terminated by Compute Engine (not
	// terminated by a user). You can only set the automatic restart option
	// for standard instances. Preemptible instances cannot be automatically
	// restarted.
	//
	// By default, this is set to true so an instance is automatically
	// restarted if it is terminated by Compute Engine.
	AutomaticRestart *bool `json:"automaticRestart,omitempty"`

	// NodeAffinities: A set of node affinity and anti-affinity
	// configurations. Refer to Configuring node affinity for more
	// information.
	NodeAffinities []*SchedulingNodeAffinity `json:"nodeAffinities,omitempty"`

	// OnHostMaintenance: Defines the maintenance behavior for this
	// instance. For standard instances, the default behavior is MIGRATE.
	// For preemptible instances, the default and only possible behavior is
	// TERMINATE. For more information, see Setting Instance Scheduling
	// Options.
	//
	// Possible values:
	//   "MIGRATE"
	//   "TERMINATE"
	OnHostMaintenance string `json:"onHostMaintenance,omitempty"`

	// Preemptible: Defines whether the instance is preemptible. This can
	// only be set during instance creation, it cannot be set or changed
	// after the instance has been created.
	Preemptible bool `json:"preemptible,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutomaticRestart") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutomaticRestart") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Scheduling) MarshalJSON() ([]byte, error) {
	type NoMethod Scheduling
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SchedulingNodeAffinity: Node Affinity: the configuration of desired
// nodes onto which this Instance could be scheduled.
type SchedulingNodeAffinity struct {
	// Key: Corresponds to the label key of Node resource.
	Key string `json:"key,omitempty"`

	// Operator: Defines the operation of node selection. Valid operators
	// are IN for affinity and NOT_IN for anti-affinity.
	//
	// Possible values:
	//   "IN"
	//   "NOT_IN"
	//   "OPERATOR_UNSPECIFIED"
	Operator string `json:"operator,omitempty"`

	// Values: Corresponds to the label values of Node resource.
	Values []string `json:"values,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SchedulingNodeAffinity) MarshalJSON() ([]byte, error) {
	type NoMethod SchedulingNodeAffinity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecurityPolicy: Represents a Cloud Armor Security Policy
// resource.
//
// Only external backend services that use load balancers can reference
// a Security Policy. For more information, read  Cloud Armor Security
// Policy Concepts. (== resource_for v1.securityPolicies ==) (==
// resource_for beta.securityPolicies ==)
type SecurityPolicy struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Fingerprint: Specifies a fingerprint for this resource, which is
	// essentially a hash of the metadata's contents and used for optimistic
	// locking. The fingerprint is initially generated by Compute Engine and
	// changes after every request to modify or update metadata. You must
	// always provide an up-to-date fingerprint hash in order to update or
	// change metadata, otherwise the request will fail with error 412
	// conditionNotMet.
	//
	// To see the latest fingerprint, make get() request to the security
	// policy.
	Fingerprint string `json:"fingerprint,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output only] Type of the resource. Always
	// compute#securityPolicyfor security policies
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Rules: A list of rules that belong to this policy. There must always
	// be a default rule (rule with priority 2147483647 and match "*"). If
	// no rules are provided when creating a security policy, a default rule
	// with action "allow" will be added.
	Rules []*SecurityPolicyRule `json:"rules,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SecurityPolicyList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of SecurityPolicy resources.
	Items []*SecurityPolicy `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#securityPolicyList for listsof securityPolicies
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *SecurityPolicyListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicyList) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicyList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecurityPolicyListWarning: [Output Only] Informational warning
// message.
type SecurityPolicyListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SecurityPolicyListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicyListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicyListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SecurityPolicyListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicyListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicyListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SecurityPolicyReference struct {
	SecurityPolicy string `json:"securityPolicy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SecurityPolicy") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SecurityPolicy") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicyReference) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicyReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecurityPolicyRule: Represents a rule that describes one or more
// match conditions along with the action to be taken when traffic
// matches this condition (allow or deny).
type SecurityPolicyRule struct {
	// Action: The Action to preform when the client connection triggers the
	// rule. Can currently be either "allow" or "deny()" where valid values
	// for status are 403, 404, and 502.
	Action string `json:"action,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Kind: [Output only] Type of the resource. Always
	// compute#securityPolicyRule for security policy rules
	Kind string `json:"kind,omitempty"`

	// Match: A match condition that incoming traffic is evaluated against.
	// If it evaluates to true, the corresponding ?action? is enforced.
	Match *SecurityPolicyRuleMatcher `json:"match,omitempty"`

	// Preview: If set to true, the specified action is not enforced.
	Preview bool `json:"preview,omitempty"`

	// Priority: An integer indicating the priority of a rule in the list.
	// The priority must be a positive value between 0 and 2147483647. Rules
	// are evaluated from highest to lowest priority where 0 is the highest
	// priority and 2147483647 is the lowest prority.
	Priority int64 `json:"priority,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Action") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Action") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicyRule) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicyRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecurityPolicyRuleMatcher: Represents a match condition that incoming
// traffic is evaluated against. Exactly one field must be specified.
type SecurityPolicyRuleMatcher struct {
	// Config: The configuration options available when specifying
	// versioned_expr. This field must be specified if versioned_expr is
	// specified and cannot be specified if versioned_expr is not specified.
	Config *SecurityPolicyRuleMatcherConfig `json:"config,omitempty"`

	// VersionedExpr: Preconfigured versioned expression. If this field is
	// specified, config must also be specified. Available preconfigured
	// expressions along with their requirements are: SRC_IPS_V1 - must
	// specify the corresponding src_ip_range field in config.
	//
	// Possible values:
	//   "SRC_IPS_V1"
	VersionedExpr string `json:"versionedExpr,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Config") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Config") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicyRuleMatcher) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicyRuleMatcher
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SecurityPolicyRuleMatcherConfig struct {
	// SrcIpRanges: CIDR IP address range.
	SrcIpRanges []string `json:"srcIpRanges,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SrcIpRanges") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SrcIpRanges") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SecurityPolicyRuleMatcherConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPolicyRuleMatcherConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SerialPortOutput: An instance's serial console output.
type SerialPortOutput struct {
	// Contents: [Output Only] The contents of the console output.
	Contents string `json:"contents,omitempty"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#serialPortOutput for serial port output.
	Kind string `json:"kind,omitempty"`

	// Next: [Output Only] The position of the next byte of content from the
	// serial console output. Use this value in the next request as the
	// start parameter.
	Next int64 `json:"next,omitempty,string"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Start: The starting byte position of the output that was returned.
	// This should match the start parameter sent with the request. If the
	// serial console output exceeds the size of the buffer, older output
	// will be overwritten by newer content and the start values will be
	// mismatched.
	Start int64 `json:"start,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Contents") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Contents") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SerialPortOutput) MarshalJSON() ([]byte, error) {
	type NoMethod SerialPortOutput
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ServerBinding struct {
	// Possible values:
	//   "RESTART_NODE_ON_ANY_SERVER"
	//   "RESTART_NODE_ON_MINIMAL_SERVERS"
	//   "SERVER_BINDING_TYPE_UNSPECIFIED"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Type") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Type") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ServerBinding) MarshalJSON() ([]byte, error) {
	type NoMethod ServerBinding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ServiceAccount: A service account.
type ServiceAccount struct {
	// Email: Email address of the service account.
	Email string `json:"email,omitempty"`

	// Scopes: The list of scopes to be made available for this service
	// account.
	Scopes []string `json:"scopes,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Email") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Email") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ServiceAccount) MarshalJSON() ([]byte, error) {
	type NoMethod ServiceAccount
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShieldedInstanceConfig: A set of Shielded Instance options.
type ShieldedInstanceConfig struct {
	// EnableIntegrityMonitoring: Defines whether the instance has integrity
	// monitoring enabled.
	EnableIntegrityMonitoring bool `json:"enableIntegrityMonitoring,omitempty"`

	// EnableSecureBoot: Defines whether the instance has Secure Boot
	// enabled.
	EnableSecureBoot bool `json:"enableSecureBoot,omitempty"`

	// EnableVtpm: Defines whether the instance has the vTPM enabled.
	EnableVtpm bool `json:"enableVtpm,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "EnableIntegrityMonitoring") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "EnableIntegrityMonitoring") to include in API requests with the JSON
	// null value. By default, fields with empty values are omitted from API
	// requests. However, any field with an empty value appearing in
	// NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ShieldedInstanceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ShieldedInstanceConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShieldedInstanceIdentity: A shielded Instance identity entry.
type ShieldedInstanceIdentity struct {
	// EncryptionKey: An Endorsement Key (EK) made by the RSA 2048 algorithm
	// issued to the Shielded Instance's vTPM.
	EncryptionKey *ShieldedInstanceIdentityEntry `json:"encryptionKey,omitempty"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#shieldedInstanceIdentity for shielded Instance identity
	// entry.
	Kind string `json:"kind,omitempty"`

	// SigningKey: An Attestation Key (AK) made by the RSA 2048 algorithm
	// issued to the Shielded Instance's vTPM.
	SigningKey *ShieldedInstanceIdentityEntry `json:"signingKey,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "EncryptionKey") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EncryptionKey") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ShieldedInstanceIdentity) MarshalJSON() ([]byte, error) {
	type NoMethod ShieldedInstanceIdentity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShieldedInstanceIdentityEntry: A Shielded Instance Identity Entry.
type ShieldedInstanceIdentityEntry struct {
	// EkCert: A PEM-encoded X.509 certificate. This field can be empty.
	EkCert string `json:"ekCert,omitempty"`

	// EkPub: A PEM-encoded public key.
	EkPub string `json:"ekPub,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EkCert") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EkCert") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ShieldedInstanceIdentityEntry) MarshalJSON() ([]byte, error) {
	type NoMethod ShieldedInstanceIdentityEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShieldedInstanceIntegrityPolicy: The policy describes the baseline
// against which Instance boot integrity is measured.
type ShieldedInstanceIntegrityPolicy struct {
	// UpdateAutoLearnPolicy: Updates the integrity policy baseline using
	// the measurements from the VM instance's most recent boot.
	UpdateAutoLearnPolicy bool `json:"updateAutoLearnPolicy,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "UpdateAutoLearnPolicy") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "UpdateAutoLearnPolicy") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ShieldedInstanceIntegrityPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod ShieldedInstanceIntegrityPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SignedUrlKey: Represents a customer-supplied Signing Key used by
// Cloud CDN Signed URLs
type SignedUrlKey struct {
	// KeyName: Name of the key. The name must be 1-63 characters long, and
	// comply with RFC1035. Specifically, the name must be 1-63 characters
	// long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?`
	// which means the first character must be a lowercase letter, and all
	// following characters must be a dash, lowercase letter, or digit,
	// except the last character, which cannot be a dash.
	KeyName string `json:"keyName,omitempty"`

	// KeyValue: 128-bit key value used for signing the URL. The key value
	// must be a valid RFC 4648 Section 5 base64url encoded string.
	KeyValue string `json:"keyValue,omitempty"`

	// ForceSendFields is a list of field names (e.g. "KeyName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "KeyName") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SignedUrlKey) MarshalJSON() ([]byte, error) {
	type NoMethod SignedUrlKey
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Snapshot: Represents a Persistent Disk Snapshot resource.
//
// You can use snapshots to back up data on a regular interval. For more
// information, read  Creating persistent disk snapshots. (==
// resource_for beta.snapshots ==) (== resource_for v1.snapshots ==)
type Snapshot struct {
	// AutoCreated: [Output Only] Set to true if snapshots are automatically
	// by applying resource policy on the target disk.
	AutoCreated bool `json:"autoCreated,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// DiskSizeGb: [Output Only] Size of the source disk, specified in GB.
	DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#snapshot for
	// Snapshot resources.
	Kind string `json:"kind,omitempty"`

	// LabelFingerprint: A fingerprint for the labels being applied to this
	// snapshot, which is essentially a hash of the labels set used for
	// optimistic locking. The fingerprint is initially generated by Compute
	// Engine and changes after every request to modify or update labels.
	// You must always provide an up-to-date fingerprint hash in order to
	// update or change labels, otherwise the request will fail with error
	// 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve a
	// snapshot.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: Labels to apply to this snapshot. These can be later modified
	// by the setLabels method. Label values may be empty.
	Labels map[string]string `json:"labels,omitempty"`

	// LicenseCodes: [Output Only] Integer license codes indicating which
	// licenses are attached to this snapshot.
	LicenseCodes googleapi.Int64s `json:"licenseCodes,omitempty"`

	// Licenses: [Output Only] A list of public visible licenses that apply
	// to this snapshot. This can be because the original image had licenses
	// attached (such as a Windows image).
	Licenses []string `json:"licenses,omitempty"`

	// Name: Name of the resource; provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SnapshotEncryptionKey: Encrypts the snapshot using a
	// customer-supplied encryption key.
	//
	// After you encrypt a snapshot using a customer-supplied key, you must
	// provide the same key if you use the snapshot later. For example, you
	// must provide the encryption key when you create a disk from the
	// encrypted snapshot in a future request.
	//
	// Customer-supplied encryption keys do not protect access to metadata
	// of the snapshot.
	//
	// If you do not provide an encryption key when creating the snapshot,
	// then the snapshot will be encrypted using an automatically generated
	// key and you do not need to provide a key to use the snapshot later.
	SnapshotEncryptionKey *CustomerEncryptionKey `json:"snapshotEncryptionKey,omitempty"`

	// SourceDisk: [Output Only] The source disk used to create this
	// snapshot.
	SourceDisk string `json:"sourceDisk,omitempty"`

	// SourceDiskEncryptionKey: The customer-supplied encryption key of the
	// source disk. Required if the source disk is protected by a
	// customer-supplied encryption key.
	SourceDiskEncryptionKey *CustomerEncryptionKey `json:"sourceDiskEncryptionKey,omitempty"`

	// SourceDiskId: [Output Only] The ID value of the disk used to create
	// this snapshot. This value may be used to determine whether the
	// snapshot was taken from the current or a previous instance of a given
	// disk name.
	SourceDiskId string `json:"sourceDiskId,omitempty"`

	// Status: [Output Only] The status of the snapshot. This can be
	// CREATING, DELETING, FAILED, READY, or UPLOADING.
	//
	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "FAILED"
	//   "READY"
	//   "UPLOADING"
	Status string `json:"status,omitempty"`

	// StorageBytes: [Output Only] A size of the storage used by the
	// snapshot. As snapshots share storage, this number is expected to
	// change with snapshot creation/deletion.
	StorageBytes int64 `json:"storageBytes,omitempty,string"`

	// StorageBytesStatus: [Output Only] An indicator whether storageBytes
	// is in a stable state or it is being adjusted as a result of shared
	// storage reallocation. This status can either be UPDATING, meaning the
	// size of the snapshot is being updated, or UP_TO_DATE, meaning the
	// size of the snapshot is up-to-date.
	//
	// Possible values:
	//   "UPDATING"
	//   "UP_TO_DATE"
	StorageBytesStatus string `json:"storageBytesStatus,omitempty"`

	// StorageLocations: Cloud Storage bucket storage location of the
	// snapshot (regional or multi-regional).
	StorageLocations []string `json:"storageLocations,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AutoCreated") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoCreated") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Snapshot) MarshalJSON() ([]byte, error) {
	type NoMethod Snapshot
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SnapshotList: Contains a list of Snapshot resources.
type SnapshotList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Snapshot resources.
	Items []*Snapshot `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *SnapshotListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SnapshotList) MarshalJSON() ([]byte, error) {
	type NoMethod SnapshotList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SnapshotListWarning: [Output Only] Informational warning message.
type SnapshotListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SnapshotListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SnapshotListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SnapshotListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SnapshotListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SnapshotListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SnapshotListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SourceInstanceParams: A specification of the parameters to use when
// creating the instance template from a source instance.
type SourceInstanceParams struct {
	// DiskConfigs: Attached disks configuration. If not provided, defaults
	// are applied: For boot disk and any other R/W disks, new custom images
	// will be created from each disk. For read-only disks, they will be
	// attached in read-only mode. Local SSD disks will be created as blank
	// volumes.
	DiskConfigs []*DiskInstantiationConfig `json:"diskConfigs,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DiskConfigs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DiskConfigs") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SourceInstanceParams) MarshalJSON() ([]byte, error) {
	type NoMethod SourceInstanceParams
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SslCertificate: Represents an SSL Certificate resource.
//
// This SSL certificate resource also contains a private key. You can
// use SSL keys and certificates to secure connections to a load
// balancer. For more information, read  Creating and Using SSL
// Certificates. (== resource_for beta.sslCertificates ==) (==
// resource_for v1.sslCertificates ==)
type SslCertificate struct {
	// Certificate: A local certificate file. The certificate must be in PEM
	// format. The certificate chain must be no greater than 5 certs long.
	// The chain must include at least one intermediate cert.
	Certificate string `json:"certificate,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#sslCertificate for SSL certificates.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// PrivateKey: A write-only private key in PEM format. Only insert
	// requests will include this field.
	PrivateKey string `json:"privateKey,omitempty"`

	// Region: [Output Only] URL of the region where the regional SSL
	// Certificate resides. This field is not applicable to global SSL
	// Certificate.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Certificate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Certificate") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificate) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslCertificateAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of SslCertificatesScopedList resources.
	Items map[string]SslCertificatesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#sslCertificateAggregatedList for lists of SSL Certificates.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *SslCertificateAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificateAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificateAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SslCertificateAggregatedListWarning: [Output Only] Informational
// warning message.
type SslCertificateAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SslCertificateAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificateAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificateAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslCertificateAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificateAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificateAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SslCertificateList: Contains a list of SslCertificate resources.
type SslCertificateList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of SslCertificate resources.
	Items []*SslCertificate `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *SslCertificateListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificateList) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificateList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SslCertificateListWarning: [Output Only] Informational warning
// message.
type SslCertificateListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SslCertificateListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificateListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificateListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslCertificateListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificateListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificateListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslCertificatesScopedList struct {
	// SslCertificates: List of SslCertificates contained in this scope.
	SslCertificates []*SslCertificate `json:"sslCertificates,omitempty"`

	// Warning: Informational warning which replaces the list of backend
	// services when the list is empty.
	Warning *SslCertificatesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SslCertificates") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SslCertificates") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificatesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificatesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SslCertificatesScopedListWarning: Informational warning which
// replaces the list of backend services when the list is empty.
type SslCertificatesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SslCertificatesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificatesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificatesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslCertificatesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslCertificatesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SslCertificatesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslPoliciesList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of SslPolicy resources.
	Items []*SslPolicy `json:"items,omitempty"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#sslPoliciesList for lists of sslPolicies.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *SslPoliciesListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslPoliciesList) MarshalJSON() ([]byte, error) {
	type NoMethod SslPoliciesList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SslPoliciesListWarning: [Output Only] Informational warning message.
type SslPoliciesListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SslPoliciesListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslPoliciesListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SslPoliciesListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslPoliciesListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslPoliciesListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SslPoliciesListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslPoliciesListAvailableFeaturesResponse struct {
	Features []string `json:"features,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Features") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Features") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslPoliciesListAvailableFeaturesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod SslPoliciesListAvailableFeaturesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SslPolicy: Represents a Cloud Armor Security Policy resource.
//
// Only external backend services used by HTTP or HTTPS load balancers
// can reference a Security Policy. For more information, read read
// Cloud Armor Security Policy Concepts. (== resource_for
// beta.sslPolicies ==) (== resource_for v1.sslPolicies ==)
type SslPolicy struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// CustomFeatures: A list of features enabled when the selected profile
	// is CUSTOM. The
	// - method returns the set of features that can be specified in this
	// list. This field must be empty if the profile is not CUSTOM.
	CustomFeatures []string `json:"customFeatures,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// EnabledFeatures: [Output Only] The list of features enabled in the
	// SSL policy.
	EnabledFeatures []string `json:"enabledFeatures,omitempty"`

	// Fingerprint: Fingerprint of this resource. A hash of the contents
	// stored in this object. This field is used in optimistic locking. This
	// field will be ignored when inserting a SslPolicy. An up-to-date
	// fingerprint must be provided in order to update the SslPolicy,
	// otherwise the request will fail with error 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve an
	// SslPolicy.
	Fingerprint string `json:"fingerprint,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output only] Type of the resource. Always compute#sslPolicyfor
	// SSL policies.
	Kind string `json:"kind,omitempty"`

	// MinTlsVersion: The minimum version of SSL protocol that can be used
	// by the clients to establish a connection with the load balancer. This
	// can be one of TLS_1_0, TLS_1_1, TLS_1_2.
	//
	// Possible values:
	//   "TLS_1_0"
	//   "TLS_1_1"
	//   "TLS_1_2"
	MinTlsVersion string `json:"minTlsVersion,omitempty"`

	// Name: Name of the resource. The name must be 1-63 characters long,
	// and comply with RFC1035. Specifically, the name must be 1-63
	// characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Name string `json:"name,omitempty"`

	// Profile: Profile specifies the set of SSL features that can be used
	// by the load balancer when negotiating SSL with clients. This can be
	// one of COMPATIBLE, MODERN, RESTRICTED, or CUSTOM. If using CUSTOM,
	// the set of SSL features to enable must be specified in the
	// customFeatures field.
	//
	// Possible values:
	//   "COMPATIBLE"
	//   "CUSTOM"
	//   "MODERN"
	//   "RESTRICTED"
	Profile string `json:"profile,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warnings: [Output Only] If potential misconfigurations are detected
	// for this SSL policy, this field will be populated with warning
	// messages.
	Warnings []*SslPolicyWarnings `json:"warnings,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SslPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod SslPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslPolicyWarnings struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SslPolicyWarningsData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslPolicyWarnings) MarshalJSON() ([]byte, error) {
	type NoMethod SslPolicyWarnings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslPolicyWarningsData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslPolicyWarningsData) MarshalJSON() ([]byte, error) {
	type NoMethod SslPolicyWarningsData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SslPolicyReference struct {
	// SslPolicy: URL of the SSL policy resource. Set this to empty string
	// to clear any existing SSL policy associated with the target proxy
	// resource.
	SslPolicy string `json:"sslPolicy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SslPolicy") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SslPolicy") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SslPolicyReference) MarshalJSON() ([]byte, error) {
	type NoMethod SslPolicyReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Subnetwork: Represents a Subnetwork resource.
//
// A subnetwork (also known as a subnet) is a logical partition of a
// Virtual Private Cloud network with one primary IP range and zero or
// more secondary IP ranges. For more information, read  Virtual Private
// Cloud (VPC) Network. (== resource_for beta.subnetworks ==) (==
// resource_for v1.subnetworks ==)
type Subnetwork struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource. This field can be set only at
	// resource creation time.
	Description string `json:"description,omitempty"`

	// EnableFlowLogs: Whether to enable flow logging for this subnetwork.
	// If this field is not explicitly set, it will not appear in get
	// listings. If not set the default behavior is to disable flow logging.
	EnableFlowLogs bool `json:"enableFlowLogs,omitempty"`

	// Fingerprint: Fingerprint of this resource. A hash of the contents
	// stored in this object. This field is used in optimistic locking. This
	// field will be ignored when inserting a Subnetwork. An up-to-date
	// fingerprint must be provided in order to update the Subnetwork,
	// otherwise the request will fail with error 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve a
	// Subnetwork.
	Fingerprint string `json:"fingerprint,omitempty"`

	// GatewayAddress: [Output Only] The gateway address for default routes
	// to reach destination addresses outside this subnetwork.
	GatewayAddress string `json:"gatewayAddress,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// IpCidrRange: The range of internal addresses that are owned by this
	// subnetwork. Provide this property when you create the subnetwork. For
	// example, 10.0.0.0/8 or 192.168.0.0/16. Ranges must be unique and
	// non-overlapping within a network. Only IPv4 is supported. This field
	// can be set only at resource creation time.
	IpCidrRange string `json:"ipCidrRange,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#subnetwork
	// for Subnetwork resources.
	Kind string `json:"kind,omitempty"`

	// LogConfig: This field denotes the VPC flow logging options for this
	// subnetwork. If logging is enabled, logs are exported to Stackdriver.
	LogConfig *SubnetworkLogConfig `json:"logConfig,omitempty"`

	// Name: The name of the resource, provided by the client when initially
	// creating the resource. The name must be 1-63 characters long, and
	// comply with RFC1035. Specifically, the name must be 1-63 characters
	// long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?`
	// which means the first character must be a lowercase letter, and all
	// following characters must be a dash, lowercase letter, or digit,
	// except the last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Network: The URL of the network to which this subnetwork belongs,
	// provided by the client when initially creating the subnetwork. Only
	// networks that are in the distributed mode can have subnetworks. This
	// field can be set only at resource creation time.
	Network string `json:"network,omitempty"`

	// PrivateIpGoogleAccess: Whether the VMs in this subnet can access
	// Google services without assigned external IP addresses. This field
	// can be both set at resource creation time and updated using
	// setPrivateIpGoogleAccess.
	PrivateIpGoogleAccess bool `json:"privateIpGoogleAccess,omitempty"`

	// Purpose: The purpose of the resource. This field can be either
	// PRIVATE_RFC_1918 or INTERNAL_HTTPS_LOAD_BALANCER. A subnetwork with
	// purpose set to INTERNAL_HTTPS_LOAD_BALANCER is a user-created
	// subnetwork that is reserved for Internal HTTP(S) Load Balancing. If
	// unspecified, the purpose defaults to PRIVATE_RFC_1918.
	//
	// Possible values:
	//   "INTERNAL_HTTPS_LOAD_BALANCER"
	//   "PRIVATE"
	//   "PRIVATE_RFC_1918"
	Purpose string `json:"purpose,omitempty"`

	// Region: URL of the region where the Subnetwork resides. This field
	// can be set only at resource creation time.
	Region string `json:"region,omitempty"`

	// Role: The role of subnetwork. Currenly, this field is only used when
	// purpose = INTERNAL_HTTPS_LOAD_BALANCER. The value can be set to
	// ACTIVE or BACKUP. An ACTIVE subnetwork is one that is currently being
	// used for Internal HTTP(S) Load Balancing. A BACKUP subnetwork is one
	// that is ready to be promoted to ACTIVE or is currently draining. This
	// field can be updated with a patch request.
	//
	// Possible values:
	//   "ACTIVE"
	//   "BACKUP"
	Role string `json:"role,omitempty"`

	// SecondaryIpRanges: An array of configurations for secondary IP ranges
	// for VM instances contained in this subnetwork. The primary IP of such
	// VM must belong to the primary ipCidrRange of the subnetwork. The
	// alias IPs may belong to either primary or secondary ranges. This
	// field can be updated with a patch request.
	SecondaryIpRanges []*SubnetworkSecondaryRange `json:"secondaryIpRanges,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// State: [Output Only] The state of the subnetwork, which can be one of
	// READY or DRAINING. A subnetwork that is READY is ready to be used.
	// The state of DRAINING is only applicable to subnetworks that have the
	// purpose set to INTERNAL_HTTPS_LOAD_BALANCER and indicates that
	// connections to the load balancer are being drained. A subnetwork that
	// is draining cannot be used or modified until it reaches a status of
	// READY.
	//
	// Possible values:
	//   "DRAINING"
	//   "READY"
	State string `json:"state,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Subnetwork) MarshalJSON() ([]byte, error) {
	type NoMethod Subnetwork
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SubnetworkAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of SubnetworksScopedList resources.
	Items map[string]SubnetworksScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#subnetworkAggregatedList for aggregated lists of subnetworks.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *SubnetworkAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubnetworkAggregatedListWarning: [Output Only] Informational warning
// message.
type SubnetworkAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SubnetworkAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SubnetworkAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubnetworkList: Contains a list of Subnetwork resources.
type SubnetworkList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Subnetwork resources.
	Items []*Subnetwork `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#subnetworkList
	// for lists of subnetworks.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *SubnetworkListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkList) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubnetworkListWarning: [Output Only] Informational warning message.
type SubnetworkListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SubnetworkListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SubnetworkListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubnetworkLogConfig: The available logging options for this
// subnetwork.
type SubnetworkLogConfig struct {
	// AggregationInterval: Can only be specified if VPC flow logging for
	// this subnetwork is enabled. Toggles the aggregation interval for
	// collecting flow logs. Increasing the interval time will reduce the
	// amount of generated flow logs for long lasting connections. Default
	// is an interval of 5 seconds per connection.
	//
	// Possible values:
	//   "INTERVAL_10_MIN"
	//   "INTERVAL_15_MIN"
	//   "INTERVAL_1_MIN"
	//   "INTERVAL_30_SEC"
	//   "INTERVAL_5_MIN"
	//   "INTERVAL_5_SEC"
	AggregationInterval string `json:"aggregationInterval,omitempty"`

	// Enable: Whether to enable flow logging for this subnetwork. If this
	// field is not explicitly set, it will not appear in get listings. If
	// not set the default behavior is to disable flow logging.
	Enable bool `json:"enable,omitempty"`

	// FlowSampling: Can only be specified if VPC flow logging for this
	// subnetwork is enabled. The value of the field must be in [0, 1]. Set
	// the sampling rate of VPC flow logs within the subnetwork where 1.0
	// means all collected logs are reported and 0.0 means no logs are
	// reported. Default is 0.5, which means half of all collected logs are
	// reported.
	FlowSampling float64 `json:"flowSampling,omitempty"`

	// Metadata: Can only be specified if VPC flow logs for this subnetwork
	// is enabled. Configures whether all, none or a subset of metadata
	// fields should be added to the reported VPC flow logs. Default is
	// INCLUDE_ALL_METADATA.
	//
	// Possible values:
	//   "EXCLUDE_ALL_METADATA"
	//   "INCLUDE_ALL_METADATA"
	Metadata string `json:"metadata,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AggregationInterval")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AggregationInterval") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkLogConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkLogConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *SubnetworkLogConfig) UnmarshalJSON(data []byte) error {
	type NoMethod SubnetworkLogConfig
	var s1 struct {
		FlowSampling gensupport.JSONFloat64 `json:"flowSampling"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.FlowSampling = float64(s1.FlowSampling)
	return nil
}

// SubnetworkSecondaryRange: Represents a secondary IP range of a
// subnetwork.
type SubnetworkSecondaryRange struct {
	// IpCidrRange: The range of IP addresses belonging to this subnetwork
	// secondary range. Provide this property when you create the
	// subnetwork. Ranges must be unique and non-overlapping with all
	// primary and secondary IP ranges within a network. Only IPv4 is
	// supported.
	IpCidrRange string `json:"ipCidrRange,omitempty"`

	// RangeName: The name associated with this subnetwork secondary range,
	// used when adding an alias IP range to a VM instance. The name must be
	// 1-63 characters long, and comply with RFC1035. The name must be
	// unique within the subnetwork.
	RangeName string `json:"rangeName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpCidrRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpCidrRange") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworkSecondaryRange) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworkSecondaryRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SubnetworksExpandIpCidrRangeRequest struct {
	// IpCidrRange: The IP (in CIDR format or netmask) of internal addresses
	// that are legal on this Subnetwork. This range should be disjoint from
	// other subnetworks within this network. This range can only be larger
	// than (i.e. a superset of) the range previously defined before the
	// update.
	IpCidrRange string `json:"ipCidrRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpCidrRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpCidrRange") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworksExpandIpCidrRangeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworksExpandIpCidrRangeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SubnetworksScopedList struct {
	// Subnetworks: A list of subnetworks contained in this scope.
	Subnetworks []*Subnetwork `json:"subnetworks,omitempty"`

	// Warning: An informational warning that appears when the list of
	// addresses is empty.
	Warning *SubnetworksScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Subnetworks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Subnetworks") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworksScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworksScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubnetworksScopedListWarning: An informational warning that appears
// when the list of addresses is empty.
type SubnetworksScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*SubnetworksScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworksScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworksScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SubnetworksScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworksScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworksScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SubnetworksSetPrivateIpGoogleAccessRequest struct {
	PrivateIpGoogleAccess bool `json:"privateIpGoogleAccess,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PrivateIpGoogleAccess") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PrivateIpGoogleAccess") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SubnetworksSetPrivateIpGoogleAccessRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SubnetworksSetPrivateIpGoogleAccessRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TCPHealthCheck struct {
	// Port: The TCP port number for the health check request. The default
	// value is 80. Valid values are 1 through 65535.
	Port int64 `json:"port,omitempty"`

	// PortName: Port name as defined in InstanceGroup#NamedPort#name. If
	// both port and port_name are defined, port takes precedence.
	PortName string `json:"portName,omitempty"`

	// PortSpecification: Specifies how port is selected for health
	// checking, can be one of following values:
	// USE_FIXED_PORT: The port number in
	// port
	// is used for health checking.
	// USE_NAMED_PORT: The
	// portName
	// is used for health checking.
	// USE_SERVING_PORT: For NetworkEndpointGroup, the port specified for
	// each network endpoint is used for health checking. For other
	// backends, the port or named port specified in the Backend Service is
	// used for health checking.
	//
	//
	// If not specified, TCP health check follows behavior specified
	// in
	// port
	// and
	// portName
	// fields.
	//
	// Possible values:
	//   "USE_FIXED_PORT"
	//   "USE_NAMED_PORT"
	//   "USE_SERVING_PORT"
	PortSpecification string `json:"portSpecification,omitempty"`

	// ProxyHeader: Specifies the type of proxy header to append before
	// sending data to the backend, either NONE or PROXY_V1. The default is
	// NONE.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// Request: The application data to send once the TCP connection has
	// been established (default value is empty). If both request and
	// response are empty, the connection establishment alone will indicate
	// health. The request data can only be ASCII.
	Request string `json:"request,omitempty"`

	// Response: The bytes to match against the beginning of the response
	// data. If left empty (the default value), any response will indicate
	// health. The response data can only be ASCII.
	Response string `json:"response,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Port") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Port") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TCPHealthCheck) MarshalJSON() ([]byte, error) {
	type NoMethod TCPHealthCheck
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Tags: A set of instance tags.
type Tags struct {
	// Fingerprint: Specifies a fingerprint for this request, which is
	// essentially a hash of the tags' contents and used for optimistic
	// locking. The fingerprint is initially generated by Compute Engine and
	// changes after every request to modify or update tags. You must always
	// provide an up-to-date fingerprint hash in order to update or change
	// tags.
	//
	// To see the latest fingerprint, make get() request to the instance.
	Fingerprint string `json:"fingerprint,omitempty"`

	// Items: An array of tags. Each tag must be 1-63 characters long, and
	// comply with RFC1035.
	Items []string `json:"items,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fingerprint") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Tags) MarshalJSON() ([]byte, error) {
	type NoMethod Tags
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpProxiesScopedList struct {
	// TargetHttpProxies: A list of TargetHttpProxies contained in this
	// scope.
	TargetHttpProxies []*TargetHttpProxy `json:"targetHttpProxies,omitempty"`

	// Warning: Informational warning which replaces the list of backend
	// services when the list is empty.
	Warning *TargetHttpProxiesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetHttpProxies")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TargetHttpProxies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxiesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxiesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpProxiesScopedListWarning: Informational warning which
// replaces the list of backend services when the list is empty.
type TargetHttpProxiesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetHttpProxiesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxiesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxiesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpProxiesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxiesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxiesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpProxy: Represents a Target HTTP Proxy resource.
//
// A target HTTP proxy is a component of certain types of load
// balancers. Global forwarding rules reference a target HTTP proxy, and
// the target proxy then references a URL map. For more information,
// read Using Target Proxies. (== resource_for beta.targetHttpProxies
// ==) (== resource_for v1.targetHttpProxies ==)
type TargetHttpProxy struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of resource. Always compute#targetHttpProxy
	// for target HTTP proxies.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Region: [Output Only] URL of the region where the regional Target
	// HTTP Proxy resides. This field is not applicable to global Target
	// HTTP Proxies.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// UrlMap: URL to the UrlMap resource that defines the mapping from URL
	// to the BackendService.
	UrlMap string `json:"urlMap,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxy) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpProxyAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetHttpProxiesScopedList resources.
	Items map[string]TargetHttpProxiesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#targetHttpProxyAggregatedList for lists of Target HTTP
	// Proxies.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxyAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxyAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpProxyList: A list of TargetHttpProxy resources.
type TargetHttpProxyList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetHttpProxy resources.
	Items []*TargetHttpProxy `json:"items,omitempty"`

	// Kind: Type of resource. Always compute#targetHttpProxyList for lists
	// of target HTTP proxies.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetHttpProxyListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxyList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxyList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpProxyListWarning: [Output Only] Informational warning
// message.
type TargetHttpProxyListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetHttpProxyListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxyListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxyListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpProxyListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpProxyListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpProxyListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpsProxiesScopedList struct {
	// TargetHttpsProxies: A list of TargetHttpsProxies contained in this
	// scope.
	TargetHttpsProxies []*TargetHttpsProxy `json:"targetHttpsProxies,omitempty"`

	// Warning: Informational warning which replaces the list of backend
	// services when the list is empty.
	Warning *TargetHttpsProxiesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetHttpsProxies")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TargetHttpsProxies") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxiesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxiesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpsProxiesScopedListWarning: Informational warning which
// replaces the list of backend services when the list is empty.
type TargetHttpsProxiesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetHttpsProxiesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxiesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxiesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpsProxiesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxiesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxiesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpsProxiesSetQuicOverrideRequest struct {
	// QuicOverride: QUIC policy for the TargetHttpsProxy resource.
	//
	// Possible values:
	//   "DISABLE"
	//   "ENABLE"
	//   "NONE"
	QuicOverride string `json:"quicOverride,omitempty"`

	// ForceSendFields is a list of field names (e.g. "QuicOverride") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "QuicOverride") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxiesSetQuicOverrideRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxiesSetQuicOverrideRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpsProxiesSetSslCertificatesRequest struct {
	// SslCertificates: New set of SslCertificate resources to associate
	// with this TargetHttpsProxy resource. Currently exactly one
	// SslCertificate resource must be specified.
	SslCertificates []string `json:"sslCertificates,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SslCertificates") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SslCertificates") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxiesSetSslCertificatesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxiesSetSslCertificatesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpsProxy: Represents a Target HTTPS Proxy resource.
//
// A target HTTPS proxy is a component of certain types of load
// balancers. Global forwarding rules reference a target HTTPS proxy,
// and the target proxy then references a URL map. For more information,
// read Using Target Proxies. (== resource_for beta.targetHttpsProxies
// ==) (== resource_for v1.targetHttpsProxies ==)
type TargetHttpsProxy struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of resource. Always compute#targetHttpsProxy
	// for target HTTPS proxies.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// QuicOverride: Specifies the QUIC override policy for this
	// TargetHttpsProxy resource. This setting determines whether the load
	// balancer attempts to negotiate QUIC with clients. You can specify
	// NONE, ENABLE, or DISABLE.
	// - When quic-override is set to NONE, Google manages whether QUIC is
	// used.
	// - When quic-override is set to ENABLE, the load balancer uses QUIC
	// when possible.
	// - When quic-override is set to DISABLE, the load balancer doesn't use
	// QUIC.
	// - If the quic-override flag is not specified, NONE is implied.
	// -
	//
	// Possible values:
	//   "DISABLE"
	//   "ENABLE"
	//   "NONE"
	QuicOverride string `json:"quicOverride,omitempty"`

	// Region: [Output Only] URL of the region where the regional
	// TargetHttpsProxy resides. This field is not applicable to global
	// TargetHttpsProxies.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SslCertificates: URLs to SslCertificate resources that are used to
	// authenticate connections between users and the load balancer. At
	// least one SSL certificate must be specified. Currently, you may
	// specify up to 15 SSL certificates.
	SslCertificates []string `json:"sslCertificates,omitempty"`

	// SslPolicy: URL of SslPolicy resource that will be associated with the
	// TargetHttpsProxy resource. If not set, the TargetHttpsProxy resource
	// has no SSL policy configured.
	SslPolicy string `json:"sslPolicy,omitempty"`

	// UrlMap: A fully-qualified or valid partial URL to the UrlMap resource
	// that defines the mapping from URL to the BackendService. For example,
	// the following are all valid URLs for specifying a URL map:
	// -
	// https://www.googleapis.compute/v1/projects/project/global/urlMaps/url-map
	// - projects/project/global/urlMaps/url-map
	// - global/urlMaps/url-map
	UrlMap string `json:"urlMap,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxy) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpsProxyAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetHttpsProxiesScopedList resources.
	Items map[string]TargetHttpsProxiesScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#targetHttpsProxyAggregatedList for lists of Target HTTP
	// Proxies.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetHttpsProxyAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxyAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxyAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpsProxyAggregatedListWarning: [Output Only] Informational
// warning message.
type TargetHttpsProxyAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetHttpsProxyAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxyAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxyAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpsProxyAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxyAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxyAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpsProxyList: Contains a list of TargetHttpsProxy resources.
type TargetHttpsProxyList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetHttpsProxy resources.
	Items []*TargetHttpsProxy `json:"items,omitempty"`

	// Kind: Type of resource. Always compute#targetHttpsProxyList for lists
	// of target HTTPS proxies.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetHttpsProxyListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxyList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxyList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetHttpsProxyListWarning: [Output Only] Informational warning
// message.
type TargetHttpsProxyListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetHttpsProxyListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxyListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxyListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetHttpsProxyListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetHttpsProxyListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetHttpsProxyListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetInstance: Represents a Target Instance resource.
//
// You can use a target instance to handle traffic for one or more
// forwarding rules, which is ideal for forwarding protocol traffic that
// is managed by a single source. For example, ESP, AH, TCP, or UDP. For
// more information, read Target instances. (== resource_for
// beta.targetInstances ==) (== resource_for v1.targetInstances ==)
type TargetInstance struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Instance: A URL to the virtual machine instance that handles traffic
	// for this target instance. When creating a target instance, you can
	// provide the fully-qualified URL or a valid partial URL to the desired
	// virtual machine. For example, the following are all valid URLs:
	// -
	// https://www.googleapis.com/compute/v1/projects/project/zones/zone/instances/instance
	// - projects/project/zones/zone/instances/instance
	// - zones/zone/instances/instance
	Instance string `json:"instance,omitempty"`

	// Kind: [Output Only] The type of the resource. Always
	// compute#targetInstance for target instances.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// NatPolicy: NAT option controlling how IPs are NAT'ed to the instance.
	// Currently only NO_NAT (default value) is supported.
	//
	// Possible values:
	//   "NO_NAT"
	NatPolicy string `json:"natPolicy,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Zone: [Output Only] URL of the zone where the target instance
	// resides. You must specify this field as part of the HTTP request URL.
	// It is not settable as a field in the request body.
	Zone string `json:"zone,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstance) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstance
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetInstanceAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetInstance resources.
	Items map[string]TargetInstancesScopedList `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetInstanceAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstanceAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstanceAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetInstanceAggregatedListWarning: [Output Only] Informational
// warning message.
type TargetInstanceAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetInstanceAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstanceAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstanceAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetInstanceAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstanceAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstanceAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetInstanceList: Contains a list of TargetInstance resources.
type TargetInstanceList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetInstance resources.
	Items []*TargetInstance `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetInstanceListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstanceList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstanceList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetInstanceListWarning: [Output Only] Informational warning
// message.
type TargetInstanceListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetInstanceListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstanceListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstanceListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetInstanceListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstanceListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstanceListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetInstancesScopedList struct {
	// TargetInstances: A list of target instances contained in this scope.
	TargetInstances []*TargetInstance `json:"targetInstances,omitempty"`

	// Warning: Informational warning which replaces the list of addresses
	// when the list is empty.
	Warning *TargetInstancesScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetInstances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TargetInstances") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstancesScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstancesScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetInstancesScopedListWarning: Informational warning which
// replaces the list of addresses when the list is empty.
type TargetInstancesScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetInstancesScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstancesScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstancesScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetInstancesScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetInstancesScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetInstancesScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetPool: Represents a Target Pool resource.
//
// Target pools are used for network TCP/UDP load balancing. A target
// pool references member instances, an associated legacy
// HttpHealthCheck resource, and, optionally, a backup target pool. For
// more information, read Using target pools. (== resource_for
// beta.targetPools ==) (== resource_for v1.targetPools ==)
type TargetPool struct {
	// BackupPool: This field is applicable only when the containing target
	// pool is serving a forwarding rule as the primary pool, and its
	// failoverRatio field is properly set to a value between [0,
	// 1].
	//
	// backupPool and failoverRatio together define the fallback behavior of
	// the primary target pool: if the ratio of the healthy instances in the
	// primary pool is at or below failoverRatio, traffic arriving at the
	// load-balanced IP will be directed to the backup pool.
	//
	// In case where failoverRatio and backupPool are not set, or all the
	// instances in the backup pool are unhealthy, the traffic will be
	// directed back to the primary pool in the "force" mode, where traffic
	// will be spread to the healthy instances with the best effort, or to
	// all instances when no instance is healthy.
	BackupPool string `json:"backupPool,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// FailoverRatio: This field is applicable only when the containing
	// target pool is serving a forwarding rule as the primary pool (i.e.,
	// not as a backup pool to some other target pool). The value of the
	// field must be in [0, 1].
	//
	// If set, backupPool must also be set. They together define the
	// fallback behavior of the primary target pool: if the ratio of the
	// healthy instances in the primary pool is at or below this number,
	// traffic arriving at the load-balanced IP will be directed to the
	// backup pool.
	//
	// In case where failoverRatio is not set or all the instances in the
	// backup pool are unhealthy, the traffic will be directed back to the
	// primary pool in the "force" mode, where traffic will be spread to the
	// healthy instances with the best effort, or to all instances when no
	// instance is healthy.
	FailoverRatio float64 `json:"failoverRatio,omitempty"`

	// HealthChecks: The URL of the HttpHealthCheck resource. A member
	// instance in this pool is considered healthy if and only if the health
	// checks pass. An empty list means all member instances will be
	// considered healthy at all times. Only HttpHealthChecks are supported.
	// Only one health check may be specified.
	HealthChecks []string `json:"healthChecks,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Instances: A list of resource URLs to the virtual machine instances
	// serving this pool. They must live in zones contained in the same
	// region as this pool.
	Instances []string `json:"instances,omitempty"`

	// Kind: [Output Only] Type of the resource. Always compute#targetPool
	// for target pools.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Region: [Output Only] URL of the region where the target pool
	// resides.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SessionAffinity: Session affinity option, must be one of the
	// following values:
	// NONE: Connections from the same client IP may go to any instance in
	// the pool.
	// CLIENT_IP: Connections from the same client IP will go to the same
	// instance in the pool while that instance remains
	// healthy.
	// CLIENT_IP_PROTO: Connections from the same client IP with the same IP
	// protocol will go to the same instance in the pool while that instance
	// remains healthy.
	//
	// Possible values:
	//   "CLIENT_IP"
	//   "CLIENT_IP_PORT_PROTO"
	//   "CLIENT_IP_PROTO"
	//   "GENERATED_COOKIE"
	//   "HEADER_FIELD"
	//   "HTTP_COOKIE"
	//   "NONE"
	SessionAffinity string `json:"sessionAffinity,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "BackupPool") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackupPool") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPool) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPool
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *TargetPool) UnmarshalJSON(data []byte) error {
	type NoMethod TargetPool
	var s1 struct {
		FailoverRatio gensupport.JSONFloat64 `json:"failoverRatio"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.FailoverRatio = float64(s1.FailoverRatio)
	return nil
}

type TargetPoolAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetPool resources.
	Items map[string]TargetPoolsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#targetPoolAggregatedList for aggregated lists of target
	// pools.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetPoolAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetPoolAggregatedListWarning: [Output Only] Informational warning
// message.
type TargetPoolAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetPoolAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolInstanceHealth struct {
	HealthStatus []*HealthStatus `json:"healthStatus,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#targetPoolInstanceHealth when checking the health of an
	// instance.
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "HealthStatus") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthStatus") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolInstanceHealth) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolInstanceHealth
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetPoolList: Contains a list of TargetPool resources.
type TargetPoolList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetPool resources.
	Items []*TargetPool `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#targetPoolList
	// for lists of target pools.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetPoolListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetPoolListWarning: [Output Only] Informational warning message.
type TargetPoolListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetPoolListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolsAddHealthCheckRequest struct {
	// HealthChecks: The HttpHealthCheck to add to the target pool.
	HealthChecks []*HealthCheckReference `json:"healthChecks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HealthChecks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthChecks") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolsAddHealthCheckRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolsAddHealthCheckRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolsAddInstanceRequest struct {
	// Instances: A full or partial URL to an instance to add to this target
	// pool. This can be a full or partial URL. For example, the following
	// are valid URLs:
	// -
	// https://www.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name
	// - projects/project-id/zones/zone/instances/instance-name
	// - zones/zone/instances/instance-name
	Instances []*InstanceReference `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolsAddInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolsAddInstanceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolsRemoveHealthCheckRequest struct {
	// HealthChecks: Health check URL to be removed. This can be a full or
	// valid partial URL. For example, the following are valid URLs:
	// -
	// https://www.googleapis.com/compute/beta/projects/project/global/httpHealthChecks/health-check
	// - projects/project/global/httpHealthChecks/health-check
	// - global/httpHealthChecks/health-check
	HealthChecks []*HealthCheckReference `json:"healthChecks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HealthChecks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HealthChecks") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolsRemoveHealthCheckRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolsRemoveHealthCheckRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolsRemoveInstanceRequest struct {
	// Instances: URLs of the instances to be removed from target pool.
	Instances []*InstanceReference `json:"instances,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Instances") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolsRemoveInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolsRemoveInstanceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolsScopedList struct {
	// TargetPools: A list of target pools contained in this scope.
	TargetPools []*TargetPool `json:"targetPools,omitempty"`

	// Warning: Informational warning which replaces the list of addresses
	// when the list is empty.
	Warning *TargetPoolsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetPools") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TargetPools") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetPoolsScopedListWarning: Informational warning which replaces
// the list of addresses when the list is empty.
type TargetPoolsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetPoolsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetPoolsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetPoolsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetPoolsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetReference struct {
	Target string `json:"target,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Target") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Target") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetReference) MarshalJSON() ([]byte, error) {
	type NoMethod TargetReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetSslProxiesSetBackendServiceRequest struct {
	// Service: The URL of the new BackendService resource for the
	// targetSslProxy.
	Service string `json:"service,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Service") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Service") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetSslProxiesSetBackendServiceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetSslProxiesSetBackendServiceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetSslProxiesSetProxyHeaderRequest struct {
	// ProxyHeader: The new type of proxy header to append before sending
	// data to the backend. NONE or PROXY_V1 are allowed.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ProxyHeader") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ProxyHeader") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetSslProxiesSetProxyHeaderRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetSslProxiesSetProxyHeaderRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetSslProxiesSetSslCertificatesRequest struct {
	// SslCertificates: New set of URLs to SslCertificate resources to
	// associate with this TargetSslProxy. Currently exactly one ssl
	// certificate must be specified.
	SslCertificates []string `json:"sslCertificates,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SslCertificates") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SslCertificates") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetSslProxiesSetSslCertificatesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetSslProxiesSetSslCertificatesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetSslProxy: Represents a Target SSL Proxy resource.
//
// A target SSL proxy is a component of a SSL Proxy load balancer.
// Global forwarding rules reference a target SSL proxy, and the target
// proxy then references an external backend service. For more
// information, read Using Target Proxies. (== resource_for
// beta.targetSslProxies ==) (== resource_for v1.targetSslProxies ==)
type TargetSslProxy struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#targetSslProxy for target SSL proxies.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// ProxyHeader: Specifies the type of proxy header to append before
	// sending data to the backend, either NONE or PROXY_V1. The default is
	// NONE.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Service: URL to the BackendService resource.
	Service string `json:"service,omitempty"`

	// SslCertificates: URLs to SslCertificate resources that are used to
	// authenticate connections to Backends. At least one SSL certificate
	// must be specified. Currently, you may specify up to 15 SSL
	// certificates.
	SslCertificates []string `json:"sslCertificates,omitempty"`

	// SslPolicy: URL of SslPolicy resource that will be associated with the
	// TargetSslProxy resource. If not set, the TargetSslProxy resource will
	// not have any SSL policy configured.
	SslPolicy string `json:"sslPolicy,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetSslProxy) MarshalJSON() ([]byte, error) {
	type NoMethod TargetSslProxy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetSslProxyList: Contains a list of TargetSslProxy resources.
type TargetSslProxyList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetSslProxy resources.
	Items []*TargetSslProxy `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetSslProxyListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetSslProxyList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetSslProxyList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetSslProxyListWarning: [Output Only] Informational warning
// message.
type TargetSslProxyListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetSslProxyListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetSslProxyListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetSslProxyListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetSslProxyListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetSslProxyListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetSslProxyListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetTcpProxiesSetBackendServiceRequest struct {
	// Service: The URL of the new BackendService resource for the
	// targetTcpProxy.
	Service string `json:"service,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Service") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Service") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetTcpProxiesSetBackendServiceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetTcpProxiesSetBackendServiceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetTcpProxiesSetProxyHeaderRequest struct {
	// ProxyHeader: The new type of proxy header to append before sending
	// data to the backend. NONE or PROXY_V1 are allowed.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ProxyHeader") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ProxyHeader") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetTcpProxiesSetProxyHeaderRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TargetTcpProxiesSetProxyHeaderRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetTcpProxy: Represents a Target TCP Proxy resource.
//
// A target TCP proxy is a component of a TCP Proxy load balancer.
// Global forwarding rules reference target TCP proxy, and the target
// proxy then references an external backend service. For more
// information, read TCP Proxy Load Balancing Concepts. (== resource_for
// beta.targetTcpProxies ==) (== resource_for v1.targetTcpProxies ==)
type TargetTcpProxy struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always
	// compute#targetTcpProxy for target TCP proxies.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// ProxyHeader: Specifies the type of proxy header to append before
	// sending data to the backend, either NONE or PROXY_V1. The default is
	// NONE.
	//
	// Possible values:
	//   "NONE"
	//   "PROXY_V1"
	ProxyHeader string `json:"proxyHeader,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Service: URL to the BackendService resource.
	Service string `json:"service,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetTcpProxy) MarshalJSON() ([]byte, error) {
	type NoMethod TargetTcpProxy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetTcpProxyList: Contains a list of TargetTcpProxy resources.
type TargetTcpProxyList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetTcpProxy resources.
	Items []*TargetTcpProxy `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetTcpProxyListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetTcpProxyList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetTcpProxyList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetTcpProxyListWarning: [Output Only] Informational warning
// message.
type TargetTcpProxyListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetTcpProxyListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetTcpProxyListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetTcpProxyListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetTcpProxyListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetTcpProxyListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetTcpProxyListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetVpnGateway: Represents a Target VPN Gateway resource.
//
// The target VPN gateway resource represents a Classic Cloud VPN
// gateway. For more information, read the the Cloud VPN Overview. (==
// resource_for beta.targetVpnGateways ==) (== resource_for
// v1.targetVpnGateways ==)
type TargetVpnGateway struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// ForwardingRules: [Output Only] A list of URLs to the ForwardingRule
	// resources. ForwardingRules are created using
	// compute.forwardingRules.insert and associated with a VPN gateway.
	ForwardingRules []string `json:"forwardingRules,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of resource. Always compute#targetVpnGateway
	// for target VPN gateways.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Network: URL of the network to which this VPN gateway is attached.
	// Provided by the client when the VPN gateway is created.
	Network string `json:"network,omitempty"`

	// Region: [Output Only] URL of the region where the target VPN gateway
	// resides. You must specify this field as part of the HTTP request URL.
	// It is not settable as a field in the request body.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Status: [Output Only] The status of the VPN gateway, which can be one
	// of the following: CREATING, READY, FAILED, or DELETING.
	//
	// Possible values:
	//   "CREATING"
	//   "DELETING"
	//   "FAILED"
	//   "READY"
	Status string `json:"status,omitempty"`

	// Tunnels: [Output Only] A list of URLs to VpnTunnel resources.
	// VpnTunnels are created using the compute.vpntunnels.insert method and
	// associated with a VPN gateway.
	Tunnels []string `json:"tunnels,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGateway) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGateway
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetVpnGatewayAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetVpnGateway resources.
	Items map[string]TargetVpnGatewaysScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#targetVpnGateway
	// for target VPN gateways.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetVpnGatewayAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewayAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewayAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetVpnGatewayAggregatedListWarning: [Output Only] Informational
// warning message.
type TargetVpnGatewayAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetVpnGatewayAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewayAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewayAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetVpnGatewayAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewayAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewayAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetVpnGatewayList: Contains a list of TargetVpnGateway resources.
type TargetVpnGatewayList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of TargetVpnGateway resources.
	Items []*TargetVpnGateway `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#targetVpnGateway
	// for target VPN gateways.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *TargetVpnGatewayListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewayList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewayList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetVpnGatewayListWarning: [Output Only] Informational warning
// message.
type TargetVpnGatewayListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetVpnGatewayListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewayListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewayListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetVpnGatewayListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewayListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewayListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetVpnGatewaysScopedList struct {
	// TargetVpnGateways: [Output Only] A list of target VPN gateways
	// contained in this scope.
	TargetVpnGateways []*TargetVpnGateway `json:"targetVpnGateways,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of addresses when the list is empty.
	Warning *TargetVpnGatewaysScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetVpnGateways")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TargetVpnGateways") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewaysScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewaysScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetVpnGatewaysScopedListWarning: [Output Only] Informational
// warning which replaces the list of addresses when the list is empty.
type TargetVpnGatewaysScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*TargetVpnGatewaysScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewaysScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewaysScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TargetVpnGatewaysScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TargetVpnGatewaysScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod TargetVpnGatewaysScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TestFailure struct {
	ActualService string `json:"actualService,omitempty"`

	ExpectedService string `json:"expectedService,omitempty"`

	Host string `json:"host,omitempty"`

	Path string `json:"path,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActualService") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ActualService") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestFailure) MarshalJSON() ([]byte, error) {
	type NoMethod TestFailure
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TestPermissionsRequest struct {
	// Permissions: The set of permissions to check for the 'resource'.
	// Permissions with wildcards (such as '*' or 'storage.*') are not
	// allowed.
	Permissions []string `json:"permissions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Permissions") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Permissions") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestPermissionsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TestPermissionsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TestPermissionsResponse struct {
	// Permissions: A subset of `TestPermissionsRequest.permissions` that
	// the caller is allowed.
	Permissions []string `json:"permissions,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Permissions") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Permissions") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestPermissionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod TestPermissionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlMap: Represents a URL Map resource.
//
// A URL map resource is a component of certain types of load balancers.
// This resource defines mappings from host names and URL paths to
// either a backend service or a backend bucket.
//
// To use this resource, the backend service must have a
// loadBalancingScheme of either EXTERNAL, INTERNAL_SELF_MANAGED, or
// INTERNAL_MANAGED For more information, read URL Map Concepts.
type UrlMap struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// DefaultRouteAction: defaultRouteAction takes effect when none of the
	// hostRules match. The load balancer performs advanced routing actions
	// like URL rewrites, header transformations, etc. prior to forwarding
	// the request to the selected backend. If defaultRouteAction specifies
	// any weightedBackendServices, defaultService must not be set.
	// Conversely if defaultService is set, defaultRouteAction cannot
	// contain any  weightedBackendServices.
	// Only one of defaultRouteAction or defaultUrlRedirect must be set.
	DefaultRouteAction *HttpRouteAction `json:"defaultRouteAction,omitempty"`

	// DefaultService: The full or partial URL of the defaultService
	// resource to which traffic is directed if none of the hostRules match.
	// If defaultRouteAction is additionally specified, advanced routing
	// actions like URL Rewrites, etc. take effect prior to sending the
	// request to the backend. However, if defaultService is specified,
	// defaultRouteAction cannot contain any weightedBackendServices.
	// Conversely, if routeAction specifies any weightedBackendServices,
	// service must not be specified.
	// Only one of defaultService, defaultUrlRedirect  or
	// defaultRouteAction.weightedBackendService must be set.
	DefaultService string `json:"defaultService,omitempty"`

	// DefaultUrlRedirect: When none of the specified hostRules match, the
	// request is redirected to a URL specified by defaultUrlRedirect.
	// If defaultUrlRedirect is specified, defaultService or
	// defaultRouteAction must not be set.
	DefaultUrlRedirect *HttpRedirectAction `json:"defaultUrlRedirect,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Fingerprint: Fingerprint of this resource. A hash of the contents
	// stored in this object. This field is used in optimistic locking. This
	// field will be ignored when inserting a UrlMap. An up-to-date
	// fingerprint must be provided in order to update the UrlMap, otherwise
	// the request will fail with error 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve a
	// UrlMap.
	Fingerprint string `json:"fingerprint,omitempty"`

	// HeaderAction: Specifies changes to request and response headers that
	// need to take effect for the selected backendService.
	// The headerAction specified here take effect after headerAction
	// specified under pathMatcher.
	HeaderAction *HttpHeaderAction `json:"headerAction,omitempty"`

	// HostRules: The list of HostRules to use against the URL.
	HostRules []*HostRule `json:"hostRules,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#urlMaps for
	// url maps.
	Kind string `json:"kind,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// PathMatchers: The list of named PathMatchers to use against the URL.
	PathMatchers []*PathMatcher `json:"pathMatchers,omitempty"`

	// Region: [Output Only] URL of the region where the regional URL map
	// resides. This field is not applicable to global URL maps. You must
	// specify this field as part of the HTTP request URL. It is not
	// settable as a field in the request body.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Tests: The list of expected URL mapping tests. Request to update this
	// UrlMap will succeed only if all of the test cases pass. You can
	// specify a maximum of 100 tests per UrlMap.
	Tests []*UrlMapTest `json:"tests,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *UrlMap) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMap
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlMapList: Contains a list of UrlMap resources.
type UrlMapList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of UrlMap resources.
	Items []*UrlMap `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *UrlMapListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapList) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlMapListWarning: [Output Only] Informational warning message.
type UrlMapListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*UrlMapListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapReference struct {
	UrlMap string `json:"urlMap,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UrlMap") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "UrlMap") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapReference) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlMapTest: Message for the expected URL mappings.
type UrlMapTest struct {
	// Description: Description of this test case.
	Description string `json:"description,omitempty"`

	// Host: Host portion of the URL.
	Host string `json:"host,omitempty"`

	// Path: Path portion of the URL.
	Path string `json:"path,omitempty"`

	// Service: Expected BackendService resource the given URL should be
	// mapped to.
	Service string `json:"service,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapTest) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapTest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlMapValidationResult: Message representing the validation result
// for a UrlMap.
type UrlMapValidationResult struct {
	LoadErrors []string `json:"loadErrors,omitempty"`

	// LoadSucceeded: Whether the given UrlMap can be successfully loaded.
	// If false, 'loadErrors' indicates the reasons.
	LoadSucceeded bool `json:"loadSucceeded,omitempty"`

	TestFailures []*TestFailure `json:"testFailures,omitempty"`

	// TestPassed: If successfully loaded, this field indicates whether the
	// test passed. If false, 'testFailures's indicate the reason of
	// failure.
	TestPassed bool `json:"testPassed,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LoadErrors") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LoadErrors") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapValidationResult) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapValidationResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapsAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of UrlMapsScopedList resources.
	Items map[string]UrlMapsScopedList `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *UrlMapsAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlMapsAggregatedListWarning: [Output Only] Informational warning
// message.
type UrlMapsAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*UrlMapsAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapsAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapsScopedList struct {
	// UrlMaps: A list of UrlMaps contained in this scope.
	UrlMaps []*UrlMap `json:"urlMaps,omitempty"`

	// Warning: Informational warning which replaces the list of backend
	// services when the list is empty.
	Warning *UrlMapsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UrlMaps") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "UrlMaps") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlMapsScopedListWarning: Informational warning which replaces the
// list of backend services when the list is empty.
type UrlMapsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*UrlMapsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapsValidateRequest struct {
	// Resource: Content of the UrlMap to be validated.
	Resource *UrlMap `json:"resource,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Resource") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Resource") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsValidateRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsValidateRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UrlMapsValidateResponse struct {
	Result *UrlMapValidationResult `json:"result,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Result") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Result") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlMapsValidateResponse) MarshalJSON() ([]byte, error) {
	type NoMethod UrlMapsValidateResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlRewrite: The spec for modifying the path before sending the
// request to the matched backend service.
type UrlRewrite struct {
	// HostRewrite: Prior to forwarding the request to the selected service,
	// the request's host header is replaced with contents of
	// hostRewrite.
	// The value must be between 1 and 255 characters.
	HostRewrite string `json:"hostRewrite,omitempty"`

	// PathPrefixRewrite: Prior to forwarding the request to the selected
	// backend service, the matching portion of the request's path is
	// replaced by pathPrefixRewrite.
	// The value must be between 1 and 1024 characters.
	PathPrefixRewrite string `json:"pathPrefixRewrite,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HostRewrite") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HostRewrite") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UrlRewrite) MarshalJSON() ([]byte, error) {
	type NoMethod UrlRewrite
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UsableSubnetwork: Subnetwork which the current user has
// compute.subnetworks.use permission on.
type UsableSubnetwork struct {
	// IpCidrRange: The range of internal addresses that are owned by this
	// subnetwork.
	IpCidrRange string `json:"ipCidrRange,omitempty"`

	// Network: Network URL.
	Network string `json:"network,omitempty"`

	// SecondaryIpRanges: Secondary IP ranges.
	SecondaryIpRanges []*UsableSubnetworkSecondaryRange `json:"secondaryIpRanges,omitempty"`

	// Subnetwork: Subnetwork URL.
	Subnetwork string `json:"subnetwork,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpCidrRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpCidrRange") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UsableSubnetwork) MarshalJSON() ([]byte, error) {
	type NoMethod UsableSubnetwork
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UsableSubnetworkSecondaryRange: Secondary IP range of a usable
// subnetwork.
type UsableSubnetworkSecondaryRange struct {
	// IpCidrRange: The range of IP addresses belonging to this subnetwork
	// secondary range.
	IpCidrRange string `json:"ipCidrRange,omitempty"`

	// RangeName: The name associated with this subnetwork secondary range,
	// used when adding an alias IP range to a VM instance. The name must be
	// 1-63 characters long, and comply with RFC1035. The name must be
	// unique within the subnetwork.
	RangeName string `json:"rangeName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpCidrRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpCidrRange") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UsableSubnetworkSecondaryRange) MarshalJSON() ([]byte, error) {
	type NoMethod UsableSubnetworkSecondaryRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UsableSubnetworksAggregatedList struct {
	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id string `json:"id,omitempty"`

	// Items: [Output] A list of usable subnetwork URLs.
	Items []*UsableSubnetwork `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#usableSubnetworksAggregatedList for aggregated lists of
	// usable subnetworks.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *UsableSubnetworksAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UsableSubnetworksAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod UsableSubnetworksAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UsableSubnetworksAggregatedListWarning: [Output Only] Informational
// warning message.
type UsableSubnetworksAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*UsableSubnetworksAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UsableSubnetworksAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod UsableSubnetworksAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UsableSubnetworksAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UsableSubnetworksAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod UsableSubnetworksAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UsageExportLocation: The location in Cloud Storage and naming method
// of the daily usage report. Contains bucket_name and report_name
// prefix.
type UsageExportLocation struct {
	// BucketName: The name of an existing bucket in Cloud Storage where the
	// usage report object is stored. The Google Service Account is granted
	// write access to this bucket. This can either be the bucket name by
	// itself, such as example-bucket, or the bucket name with gs:// or
	// https://storage.googleapis.com/ in front of it, such as
	// gs://example-bucket.
	BucketName string `json:"bucketName,omitempty"`

	// ReportNamePrefix: An optional prefix for the name of the usage report
	// object stored in bucketName. If not supplied, defaults to usage. The
	// report is stored as a CSV file named
	// report_name_prefix_gce_YYYYMMDD.csv where YYYYMMDD is the day of the
	// usage according to Pacific Time. If you supply a prefix, it should
	// conform to Cloud Storage object naming conventions.
	ReportNamePrefix string `json:"reportNamePrefix,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BucketName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BucketName") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UsageExportLocation) MarshalJSON() ([]byte, error) {
	type NoMethod UsageExportLocation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VmEndpointNatMappings: Contain information of Nat mapping for a VM
// endpoint (i.e., NIC).
type VmEndpointNatMappings struct {
	// InstanceName: Name of the VM instance which the endpoint belongs to
	InstanceName string `json:"instanceName,omitempty"`

	InterfaceNatMappings []*VmEndpointNatMappingsInterfaceNatMappings `json:"interfaceNatMappings,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstanceName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VmEndpointNatMappings) MarshalJSON() ([]byte, error) {
	type NoMethod VmEndpointNatMappings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VmEndpointNatMappingsInterfaceNatMappings: Contain information of Nat
// mapping for an interface of this endpoint.
type VmEndpointNatMappingsInterfaceNatMappings struct {
	// DrainNatIpPortRanges: List of all drain IP:port-range mappings
	// assigned to this interface. These ranges are inclusive, that is, both
	// the first and the last ports can be used for NAT. Example:
	// ["2.2.2.2:12345-12355", "1.1.1.1:2234-2234"].
	DrainNatIpPortRanges []string `json:"drainNatIpPortRanges,omitempty"`

	// NatIpPortRanges: A list of all IP:port-range mappings assigned to
	// this interface. These ranges are inclusive, that is, both the first
	// and the last ports can be used for NAT. Example:
	// ["2.2.2.2:12345-12355", "1.1.1.1:2234-2234"].
	NatIpPortRanges []string `json:"natIpPortRanges,omitempty"`

	// NumTotalDrainNatPorts: Total number of drain ports across all NAT IPs
	// allocated to this interface. It equals to the aggregated port number
	// in the field drain_nat_ip_port_ranges.
	NumTotalDrainNatPorts int64 `json:"numTotalDrainNatPorts,omitempty"`

	// NumTotalNatPorts: Total number of ports across all NAT IPs allocated
	// to this interface. It equals to the aggregated port number in the
	// field nat_ip_port_ranges.
	NumTotalNatPorts int64 `json:"numTotalNatPorts,omitempty"`

	// SourceAliasIpRange: Alias IP range for this interface endpoint. It
	// will be a private (RFC 1918) IP range. Examples: "10.33.4.55/32", or
	// "192.168.5.0/24".
	SourceAliasIpRange string `json:"sourceAliasIpRange,omitempty"`

	// SourceVirtualIp: Primary IP of the VM for this NIC.
	SourceVirtualIp string `json:"sourceVirtualIp,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "DrainNatIpPortRanges") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DrainNatIpPortRanges") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *VmEndpointNatMappingsInterfaceNatMappings) MarshalJSON() ([]byte, error) {
	type NoMethod VmEndpointNatMappingsInterfaceNatMappings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VmEndpointNatMappingsList: Contains a list of VmEndpointNatMappings.
type VmEndpointNatMappingsList struct {
	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id string `json:"id,omitempty"`

	// Kind: [Output Only] Type of resource. Always
	// compute#vmEndpointNatMappingsList for lists of Nat mappings of VM
	// endpoints.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Result: [Output Only] A list of Nat mapping information of VM
	// endpoints.
	Result []*VmEndpointNatMappings `json:"result,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *VmEndpointNatMappingsListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VmEndpointNatMappingsList) MarshalJSON() ([]byte, error) {
	type NoMethod VmEndpointNatMappingsList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VmEndpointNatMappingsListWarning: [Output Only] Informational warning
// message.
type VmEndpointNatMappingsListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*VmEndpointNatMappingsListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VmEndpointNatMappingsListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod VmEndpointNatMappingsListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VmEndpointNatMappingsListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VmEndpointNatMappingsListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod VmEndpointNatMappingsListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGateway: Represents a VPN gateway resource.
type VpnGateway struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of resource. Always compute#vpnGateway for
	// VPN gateways.
	Kind string `json:"kind,omitempty"`

	// LabelFingerprint: A fingerprint for the labels being applied to this
	// VpnGateway, which is essentially a hash of the labels set used for
	// optimistic locking. The fingerprint is initially generated by Compute
	// Engine and changes after every request to modify or update labels.
	// You must always provide an up-to-date fingerprint hash in order to
	// update or change labels, otherwise the request will fail with error
	// 412 conditionNotMet.
	//
	// To see the latest fingerprint, make a get() request to retrieve an
	// VpnGateway.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: Labels to apply to this VpnGateway resource. These can be
	// later modified by the setLabels method. Each label key/value must
	// comply with RFC1035. Label values may be empty.
	Labels map[string]string `json:"labels,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// Network: URL of the network to which this VPN gateway is attached.
	// Provided by the client when the VPN gateway is created.
	Network string `json:"network,omitempty"`

	// Region: [Output Only] URL of the region where the VPN gateway
	// resides.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// VpnInterfaces: [Output Only] A list of interfaces on this VPN
	// gateway.
	VpnInterfaces []*VpnGatewayVpnGatewayInterface `json:"vpnInterfaces,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *VpnGateway) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGateway
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnGatewayAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of VpnGateway resources.
	Items map[string]VpnGatewaysScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#vpnGateway for
	// VPN gateways.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *VpnGatewayAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewayAggregatedListWarning: [Output Only] Informational warning
// message.
type VpnGatewayAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*VpnGatewayAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnGatewayAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewayList: Contains a list of VpnGateway resources.
type VpnGatewayList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of VpnGateway resources.
	Items []*VpnGateway `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#vpnGateway for
	// VPN gateways.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *VpnGatewayListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayList) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewayListWarning: [Output Only] Informational warning message.
type VpnGatewayListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*VpnGatewayListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnGatewayListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnGatewayStatus struct {
	// VpnConnections: List of VPN connection for this VpnGateway.
	VpnConnections []*VpnGatewayStatusVpnConnection `json:"vpnConnections,omitempty"`

	// ForceSendFields is a list of field names (e.g. "VpnConnections") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "VpnConnections") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayStatus) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewayStatusHighAvailabilityRequirementState: Describes the high
// availability requirement state for the VPN connection between this
// Cloud VPN gateway and a peer gateway.
type VpnGatewayStatusHighAvailabilityRequirementState struct {
	// State: Indicates the high availability requirement state for the VPN
	// connection. Valid values are CONNECTION_REDUNDANCY_MET,
	// CONNECTION_REDUNDANCY_NOT_MET.
	//
	// Possible values:
	//   "CONNECTION_REDUNDANCY_MET"
	//   "CONNECTION_REDUNDANCY_NOT_MET"
	State string `json:"state,omitempty"`

	// UnsatisfiedReason: Indicates the reason why the VPN connection does
	// not meet the high availability redundancy criteria/requirement. Valid
	// values is INCOMPLETE_TUNNELS_COVERAGE.
	//
	// Possible values:
	//   "INCOMPLETE_TUNNELS_COVERAGE"
	UnsatisfiedReason string `json:"unsatisfiedReason,omitempty"`

	// ForceSendFields is a list of field names (e.g. "State") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "State") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayStatusHighAvailabilityRequirementState) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayStatusHighAvailabilityRequirementState
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewayStatusTunnel: Contains some information about a VPN tunnel.
type VpnGatewayStatusTunnel struct {
	// LocalGatewayInterface: The VPN gateway interface this VPN tunnel is
	// associated with.
	LocalGatewayInterface int64 `json:"localGatewayInterface,omitempty"`

	// PeerGatewayInterface: The peer gateway interface this VPN tunnel is
	// connected to, the peer gateway could either be an external VPN
	// gateway or GCP VPN gateway.
	PeerGatewayInterface int64 `json:"peerGatewayInterface,omitempty"`

	// TunnelUrl: URL reference to the VPN tunnel.
	TunnelUrl string `json:"tunnelUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "LocalGatewayInterface") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LocalGatewayInterface") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayStatusTunnel) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayStatusTunnel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewayStatusVpnConnection: A VPN connection contains all VPN
// tunnels connected from this VpnGateway to the same peer gateway. The
// peer gateway could either be a external VPN gateway or GCP VPN
// gateway.
type VpnGatewayStatusVpnConnection struct {
	// PeerExternalGateway: URL reference to the peer external VPN gateways
	// to which the VPN tunnels in this VPN connection are connected. This
	// field is mutually exclusive with peer_gcp_gateway.
	PeerExternalGateway string `json:"peerExternalGateway,omitempty"`

	// PeerGcpGateway: URL reference to the peer side VPN gateways to which
	// the VPN tunnels in this VPN connection are connected. This field is
	// mutually exclusive with peer_gcp_gateway.
	PeerGcpGateway string `json:"peerGcpGateway,omitempty"`

	// State: HighAvailabilityRequirementState for the VPN connection.
	State *VpnGatewayStatusHighAvailabilityRequirementState `json:"state,omitempty"`

	// Tunnels: List of VPN tunnels that are in this VPN connection.
	Tunnels []*VpnGatewayStatusTunnel `json:"tunnels,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PeerExternalGateway")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PeerExternalGateway") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayStatusVpnConnection) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayStatusVpnConnection
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewayVpnGatewayInterface: A VPN gateway interface.
type VpnGatewayVpnGatewayInterface struct {
	// Id: The numeric ID of this VPN gateway interface.
	Id int64 `json:"id,omitempty"`

	// IpAddress: The external IP address for this VPN gateway interface.
	IpAddress string `json:"ipAddress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewayVpnGatewayInterface) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewayVpnGatewayInterface
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnGatewaysGetStatusResponse struct {
	Result *VpnGatewayStatus `json:"result,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Result") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Result") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewaysGetStatusResponse) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewaysGetStatusResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnGatewaysScopedList struct {
	// VpnGateways: [Output Only] A list of VPN gateways contained in this
	// scope.
	VpnGateways []*VpnGateway `json:"vpnGateways,omitempty"`

	// Warning: [Output Only] Informational warning which replaces the list
	// of addresses when the list is empty.
	Warning *VpnGatewaysScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "VpnGateways") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "VpnGateways") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewaysScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewaysScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnGatewaysScopedListWarning: [Output Only] Informational warning
// which replaces the list of addresses when the list is empty.
type VpnGatewaysScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*VpnGatewaysScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewaysScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewaysScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnGatewaysScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnGatewaysScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod VpnGatewaysScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnTunnel: Represents a Cloud VPN Tunnel resource.
//
// For more information about VPN, read the the Cloud VPN Overview. (==
// resource_for beta.vpnTunnels ==) (== resource_for v1.vpnTunnels ==)
type VpnTunnel struct {
	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Description: An optional description of this resource. Provide this
	// property when you create the resource.
	Description string `json:"description,omitempty"`

	// DetailedStatus: [Output Only] Detailed status message for the VPN
	// tunnel.
	DetailedStatus string `json:"detailedStatus,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// IkeVersion: IKE protocol version to use when establishing the VPN
	// tunnel with the peer VPN gateway. Acceptable IKE versions are 1 or 2.
	// The default version is 2.
	IkeVersion int64 `json:"ikeVersion,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#vpnTunnel for
	// VPN tunnels.
	Kind string `json:"kind,omitempty"`

	// LocalTrafficSelector: Local traffic selector to use when establishing
	// the VPN tunnel with the peer VPN gateway. The value should be a CIDR
	// formatted string, for example: 192.168.0.0/16. The ranges must be
	// disjoint. Only IPv4 is supported.
	LocalTrafficSelector []string `json:"localTrafficSelector,omitempty"`

	// Name: Name of the resource. Provided by the client when the resource
	// is created. The name must be 1-63 characters long, and comply with
	// RFC1035. Specifically, the name must be 1-63 characters long and
	// match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means
	// the first character must be a lowercase letter, and all following
	// characters must be a dash, lowercase letter, or digit, except the
	// last character, which cannot be a dash.
	Name string `json:"name,omitempty"`

	// PeerExternalGateway: URL of the peer side external VPN gateway to
	// which this VPN tunnel is connected. Provided by the client when the
	// VPN tunnel is created. This field is exclusive with the field
	// peerGcpGateway.
	PeerExternalGateway string `json:"peerExternalGateway,omitempty"`

	// PeerExternalGatewayInterface: The interface ID of the external VPN
	// gateway to which this VPN tunnel is connected. Provided by the client
	// when the VPN tunnel is created.
	PeerExternalGatewayInterface int64 `json:"peerExternalGatewayInterface,omitempty"`

	// PeerGcpGateway: URL of the peer side HA GCP VPN gateway to which this
	// VPN tunnel is connected. Provided by the client when the VPN tunnel
	// is created. This field can be used when creating highly available VPN
	// from VPC network to VPC network, the field is exclusive with the
	// field peerExternalGateway. If provided, the VPN tunnel will
	// automatically use the same vpnGatewayInterface ID in the peer GCP VPN
	// gateway.
	PeerGcpGateway string `json:"peerGcpGateway,omitempty"`

	// PeerIp: IP address of the peer VPN gateway. Only IPv4 is supported.
	PeerIp string `json:"peerIp,omitempty"`

	// Region: [Output Only] URL of the region where the VPN tunnel resides.
	// You must specify this field as part of the HTTP request URL. It is
	// not settable as a field in the request body.
	Region string `json:"region,omitempty"`

	// RemoteTrafficSelector: Remote traffic selectors to use when
	// establishing the VPN tunnel with the peer VPN gateway. The value
	// should be a CIDR formatted string, for example: 192.168.0.0/16. The
	// ranges should be disjoint. Only IPv4 is supported.
	RemoteTrafficSelector []string `json:"remoteTrafficSelector,omitempty"`

	// Router: URL of the router resource to be used for dynamic routing.
	Router string `json:"router,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// SharedSecret: Shared secret used to set the secure session between
	// the Cloud VPN gateway and the peer VPN gateway.
	SharedSecret string `json:"sharedSecret,omitempty"`

	// SharedSecretHash: Hash of the shared secret.
	SharedSecretHash string `json:"sharedSecretHash,omitempty"`

	// Status: [Output Only] The status of the VPN tunnel, which can be one
	// of the following:
	// - PROVISIONING: Resource is being allocated for the VPN tunnel.
	// - WAITING_FOR_FULL_CONFIG: Waiting to receive all VPN-related configs
	// from the user. Network, TargetVpnGateway, VpnTunnel, ForwardingRule,
	// and Route resources are needed to setup the VPN tunnel.
	// - FIRST_HANDSHAKE: Successful first handshake with the peer VPN.
	// - ESTABLISHED: Secure session is successfully established with the
	// peer VPN.
	// - NETWORK_ERROR: Deprecated, replaced by NO_INCOMING_PACKETS
	// - AUTHORIZATION_ERROR: Auth error (for example, bad shared secret).
	//
	// - NEGOTIATION_FAILURE: Handshake failed.
	// - DEPROVISIONING: Resources are being deallocated for the VPN tunnel.
	//
	// - FAILED: Tunnel creation has failed and the tunnel is not ready to
	// be used.
	// - NO_INCOMING_PACKETS: No incoming packets from peer.
	// - REJECTED: Tunnel configuration was rejected, can be result of being
	// blacklisted.
	// - ALLOCATING_RESOURCES: Cloud VPN is in the process of allocating all
	// required resources.
	// - STOPPED: Tunnel is stopped due to its Forwarding Rules being
	// deleted for Classic VPN tunnels or the project is in frozen state.
	// - PEER_IDENTITY_MISMATCH: Peer identity does not match peer IP,
	// probably behind NAT.
	// - TS_NARROWING_NOT_ALLOWED: Traffic selector narrowing not allowed
	// for an HA-VPN tunnel.
	//
	// Possible values:
	//   "ALLOCATING_RESOURCES"
	//   "AUTHORIZATION_ERROR"
	//   "DEPROVISIONING"
	//   "ESTABLISHED"
	//   "FAILED"
	//   "FIRST_HANDSHAKE"
	//   "NEGOTIATION_FAILURE"
	//   "NETWORK_ERROR"
	//   "NO_INCOMING_PACKETS"
	//   "PROVISIONING"
	//   "REJECTED"
	//   "STOPPED"
	//   "WAITING_FOR_FULL_CONFIG"
	Status string `json:"status,omitempty"`

	// TargetVpnGateway: URL of the Target VPN gateway with which this VPN
	// tunnel is associated. Provided by the client when the VPN tunnel is
	// created.
	TargetVpnGateway string `json:"targetVpnGateway,omitempty"`

	// VpnGateway: URL of the VPN gateway with which this VPN tunnel is
	// associated. Provided by the client when the VPN tunnel is created.
	// This must be used (instead of target_vpn_gateway) if a High
	// Availability VPN gateway resource is created.
	VpnGateway string `json:"vpnGateway,omitempty"`

	// VpnGatewayInterface: The interface ID of the VPN gateway with which
	// this VPN tunnel is associated.
	VpnGatewayInterface int64 `json:"vpnGatewayInterface,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTimestamp")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTimestamp") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnel) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnTunnelAggregatedList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of VpnTunnelsScopedList resources.
	Items map[string]VpnTunnelsScopedList `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#vpnTunnel for
	// VPN tunnels.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *VpnTunnelAggregatedListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelAggregatedList) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelAggregatedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnTunnelAggregatedListWarning: [Output Only] Informational warning
// message.
type VpnTunnelAggregatedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*VpnTunnelAggregatedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelAggregatedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelAggregatedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnTunnelAggregatedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelAggregatedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelAggregatedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnTunnelList: Contains a list of VpnTunnel resources.
type VpnTunnelList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of VpnTunnel resources.
	Items []*VpnTunnel `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#vpnTunnel for
	// VPN tunnels.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *VpnTunnelListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelList) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnTunnelListWarning: [Output Only] Informational warning message.
type VpnTunnelListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*VpnTunnelListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnTunnelListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnTunnelsScopedList struct {
	// VpnTunnels: A list of VPN tunnels contained in this scope.
	VpnTunnels []*VpnTunnel `json:"vpnTunnels,omitempty"`

	// Warning: Informational warning which replaces the list of addresses
	// when the list is empty.
	Warning *VpnTunnelsScopedListWarning `json:"warning,omitempty"`

	// ForceSendFields is a list of field names (e.g. "VpnTunnels") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "VpnTunnels") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelsScopedList) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelsScopedList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VpnTunnelsScopedListWarning: Informational warning which replaces the
// list of addresses when the list is empty.
type VpnTunnelsScopedListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*VpnTunnelsScopedListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelsScopedListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelsScopedListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type VpnTunnelsScopedListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VpnTunnelsScopedListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod VpnTunnelsScopedListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WeightedBackendService: In contrast to a single BackendService in
// HttpRouteAction to which all matching traffic is directed to,
// WeightedBackendService allows traffic to be split across multiple
// BackendServices. The volume of traffic for each BackendService is
// proportional to the weight specified in each WeightedBackendService
type WeightedBackendService struct {
	// BackendService: The full or partial URL to the default BackendService
	// resource. Before forwarding the request to backendService, the
	// loadbalancer applies any relevant headerActions specified as part of
	// this backendServiceWeight.
	BackendService string `json:"backendService,omitempty"`

	// HeaderAction: Specifies changes to request and response headers that
	// need to take effect for the selected backendService.
	// headerAction specified here take effect before headerAction in the
	// enclosing HttpRouteRule, PathMatcher and UrlMap.
	HeaderAction *HttpHeaderAction `json:"headerAction,omitempty"`

	// Weight: Specifies the fraction of traffic sent to backendService,
	// computed as weight / (sum of all weightedBackendService weights in
	// routeAction) .
	// The selection of a backend service is determined only for new
	// traffic. Once a user's request has been directed to a backendService,
	// subsequent requests will be sent to the same backendService as
	// determined by the BackendService's session affinity policy.
	// The value must be between 0 and 1000
	Weight int64 `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackendService") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackendService") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *WeightedBackendService) MarshalJSON() ([]byte, error) {
	type NoMethod WeightedBackendService
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type XpnHostList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: [Output Only] A list of shared VPC host project URLs.
	Items []*Project `json:"items,omitempty"`

	// Kind: [Output Only] Type of resource. Always compute#xpnHostList for
	// lists of shared VPC hosts.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *XpnHostListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *XpnHostList) MarshalJSON() ([]byte, error) {
	type NoMethod XpnHostList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// XpnHostListWarning: [Output Only] Informational warning message.
type XpnHostListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*XpnHostListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *XpnHostListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod XpnHostListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type XpnHostListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *XpnHostListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod XpnHostListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// XpnResourceId: Service resource (a.k.a service project) ID.
type XpnResourceId struct {
	// Id: The ID of the service resource. In the case of projects, this
	// field supports project id (e.g., my-project-123) and project number
	// (e.g. 12345678).
	Id string `json:"id,omitempty"`

	// Type: The type of the service resource.
	//
	// Possible values:
	//   "PROJECT"
	//   "XPN_RESOURCE_TYPE_UNSPECIFIED"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *XpnResourceId) MarshalJSON() ([]byte, error) {
	type NoMethod XpnResourceId
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Zone: Represents a Zone resource.
//
// A zone is a deployment area. These deployment areas are subsets of a
// region. For example the zone us-east1-a is located in the us-east1
// region. For more information, read Regions and Zones. (==
// resource_for beta.zones ==) (== resource_for v1.zones ==)
type Zone struct {
	// AvailableCpuPlatforms: [Output Only] Available cpu/platform
	// selections for the zone.
	AvailableCpuPlatforms []string `json:"availableCpuPlatforms,omitempty"`

	// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
	// format.
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// Deprecated: [Output Only] The deprecation status associated with this
	// zone.
	Deprecated *DeprecationStatus `json:"deprecated,omitempty"`

	// Description: [Output Only] Textual description of the resource.
	Description string `json:"description,omitempty"`

	// Id: [Output Only] The unique identifier for the resource. This
	// identifier is defined by the server.
	Id uint64 `json:"id,omitempty,string"`

	// Kind: [Output Only] Type of the resource. Always compute#zone for
	// zones.
	Kind string `json:"kind,omitempty"`

	// Name: [Output Only] Name of the resource.
	Name string `json:"name,omitempty"`

	// Region: [Output Only] Full URL reference to the region which hosts
	// the zone.
	Region string `json:"region,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for the resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Status: [Output Only] Status of the zone, either UP or DOWN.
	//
	// Possible values:
	//   "DOWN"
	//   "UP"
	Status string `json:"status,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "AvailableCpuPlatforms") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AvailableCpuPlatforms") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Zone) MarshalJSON() ([]byte, error) {
	type NoMethod Zone
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ZoneList: Contains a list of zone resources.
type ZoneList struct {
	// Id: [Output Only] Unique identifier for the resource; defined by the
	// server.
	Id string `json:"id,omitempty"`

	// Items: A list of Zone resources.
	Items []*Zone `json:"items,omitempty"`

	// Kind: Type of resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: [Output Only] This token allows you to get the next
	// page of results for list requests. If the number of results is larger
	// than maxResults, use the nextPageToken as a value for the query
	// parameter pageToken in the next list request. Subsequent list
	// requests will have their own nextPageToken to continue paging through
	// the results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SelfLink: [Output Only] Server-defined URL for this resource.
	SelfLink string `json:"selfLink,omitempty"`

	// Warning: [Output Only] Informational warning message.
	Warning *ZoneListWarning `json:"warning,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ZoneList) MarshalJSON() ([]byte, error) {
	type NoMethod ZoneList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ZoneListWarning: [Output Only] Informational warning message.
type ZoneListWarning struct {
	// Code: [Output Only] A warning code, if applicable. For example,
	// Compute Engine returns NO_RESULTS_ON_PAGE if there are no results in
	// the response.
	//
	// Possible values:
	//   "CLEANUP_FAILED"
	//   "DEPRECATED_RESOURCE_USED"
	//   "DEPRECATED_TYPE_USED"
	//   "DISK_SIZE_LARGER_THAN_IMAGE_SIZE"
	//   "EXPERIMENTAL_TYPE_USED"
	//   "EXTERNAL_API_WARNING"
	//   "FIELD_VALUE_OVERRIDEN"
	//   "INJECTED_KERNELS_DEPRECATED"
	//   "MISSING_TYPE_DEPENDENCY"
	//   "NEXT_HOP_ADDRESS_NOT_ASSIGNED"
	//   "NEXT_HOP_CANNOT_IP_FORWARD"
	//   "NEXT_HOP_INSTANCE_NOT_FOUND"
	//   "NEXT_HOP_INSTANCE_NOT_ON_NETWORK"
	//   "NEXT_HOP_NOT_RUNNING"
	//   "NOT_CRITICAL_ERROR"
	//   "NO_RESULTS_ON_PAGE"
	//   "REQUIRED_TOS_AGREEMENT"
	//   "RESOURCE_IN_USE_BY_OTHER_RESOURCE_WARNING"
	//   "RESOURCE_NOT_DELETED"
	//   "SCHEMA_VALIDATION_IGNORED"
	//   "SINGLE_INSTANCE_PROPERTY_TEMPLATE"
	//   "UNDECLARED_PROPERTIES"
	//   "UNREACHABLE"
	Code string `json:"code,omitempty"`

	// Data: [Output Only] Metadata about this warning in key: value format.
	// For example:
	// "data": [ { "key": "scope", "value": "zones/us-east1-d" }
	Data []*ZoneListWarningData `json:"data,omitempty"`

	// Message: [Output Only] A human-readable description of the warning
	// code.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ZoneListWarning) MarshalJSON() ([]byte, error) {
	type NoMethod ZoneListWarning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ZoneListWarningData struct {
	// Key: [Output Only] A key that provides more detail on the warning
	// being returned. For example, for warnings where there are no results
	// in a list request for a particular zone, this key might be scope and
	// the key value might be the zone name. Other examples might be a key
	// indicating a deprecated resource and a suggested replacement, or a
	// warning about invalid network settings (for example, if an instance
	// attempts to perform IP forwarding but is not enabled for IP
	// forwarding).
	Key string `json:"key,omitempty"`

	// Value: [Output Only] A warning data value corresponding to the key.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ZoneListWarningData) MarshalJSON() ([]byte, error) {
	type NoMethod ZoneListWarningData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ZoneSetLabelsRequest struct {
	// LabelFingerprint: The fingerprint of the previous set of labels for
	// this resource, used to detect conflicts. The fingerprint is initially
	// generated by Compute Engine and changes after every request to modify
	// or update labels. You must always provide an up-to-date fingerprint
	// hash in order to update or change labels. Make a get() request to the
	// resource to get the latest fingerprint.
	LabelFingerprint string `json:"labelFingerprint,omitempty"`

	// Labels: The labels to set for this resource.
	Labels map[string]string `json:"labels,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LabelFingerprint") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LabelFingerprint") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ZoneSetLabelsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ZoneSetLabelsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ZoneSetPolicyRequest struct {
	// Bindings: Flatten Policy to create a backwacd compatible wire-format.
	// Deprecated. Use 'policy' to specify bindings.
	Bindings []*Binding `json:"bindings,omitempty"`

	// Etag: Flatten Policy to create a backward compatible wire-format.
	// Deprecated. Use 'policy' to specify the etag.
	Etag string `json:"etag,omitempty"`

	// Policy: REQUIRED: The complete policy to be applied to the
	// 'resource'. The size of the policy is limited to a few 10s of KB. An
	// empty policy is in general a valid policy but certain services (like
	// Projects) might reject them.
	Policy *Policy `json:"policy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bindings") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bindings") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ZoneSetPolicyRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ZoneSetPolicyRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "compute.acceleratorTypes.aggregatedList":

type AcceleratorTypesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of accelerator types.
// (== suppress_warning http-rest-shadowed ==)
func (r *AcceleratorTypesService) AggregatedList(project string) *AcceleratorTypesAggregatedListCall {
	c := &AcceleratorTypesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *AcceleratorTypesAggregatedListCall) Filter(filter string) *AcceleratorTypesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *AcceleratorTypesAggregatedListCall) MaxResults(maxResults int64) *AcceleratorTypesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *AcceleratorTypesAggregatedListCall) OrderBy(orderBy string) *AcceleratorTypesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *AcceleratorTypesAggregatedListCall) PageToken(pageToken string) *AcceleratorTypesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AcceleratorTypesAggregatedListCall) Fields(s ...googleapi.Field) *AcceleratorTypesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AcceleratorTypesAggregatedListCall) IfNoneMatch(entityTag string) *AcceleratorTypesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AcceleratorTypesAggregatedListCall) Context(ctx context.Context) *AcceleratorTypesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AcceleratorTypesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AcceleratorTypesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/acceleratorTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.acceleratorTypes.aggregatedList" call.
// Exactly one of *AcceleratorTypeAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AcceleratorTypeAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AcceleratorTypesAggregatedListCall) Do(opts ...googleapi.CallOption) (*AcceleratorTypeAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AcceleratorTypeAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of accelerator types. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.acceleratorTypes.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/acceleratorTypes",
	//   "response": {
	//     "$ref": "AcceleratorTypeAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AcceleratorTypesAggregatedListCall) Pages(ctx context.Context, f func(*AcceleratorTypeAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.acceleratorTypes.get":

type AcceleratorTypesGetCall struct {
	s               *Service
	project         string
	zone            string
	acceleratorType string
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
	header_         http.Header
}

// Get: Returns the specified accelerator type. (== suppress_warning
// http-rest-shadowed ==)
func (r *AcceleratorTypesService) Get(project string, zone string, acceleratorType string) *AcceleratorTypesGetCall {
	c := &AcceleratorTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.acceleratorType = acceleratorType
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AcceleratorTypesGetCall) Fields(s ...googleapi.Field) *AcceleratorTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AcceleratorTypesGetCall) IfNoneMatch(entityTag string) *AcceleratorTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AcceleratorTypesGetCall) Context(ctx context.Context) *AcceleratorTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AcceleratorTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AcceleratorTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/acceleratorTypes/{acceleratorType}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"zone":            c.zone,
		"acceleratorType": c.acceleratorType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.acceleratorTypes.get" call.
// Exactly one of *AcceleratorType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AcceleratorType.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AcceleratorTypesGetCall) Do(opts ...googleapi.CallOption) (*AcceleratorType, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AcceleratorType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified accelerator type. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.acceleratorTypes.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "acceleratorType"
	//   ],
	//   "parameters": {
	//     "acceleratorType": {
	//       "description": "Name of the accelerator type to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/acceleratorTypes/{acceleratorType}",
	//   "response": {
	//     "$ref": "AcceleratorType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.acceleratorTypes.list":

type AcceleratorTypesListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of accelerator types available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *AcceleratorTypesService) List(project string, zone string) *AcceleratorTypesListCall {
	c := &AcceleratorTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *AcceleratorTypesListCall) Filter(filter string) *AcceleratorTypesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *AcceleratorTypesListCall) MaxResults(maxResults int64) *AcceleratorTypesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *AcceleratorTypesListCall) OrderBy(orderBy string) *AcceleratorTypesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *AcceleratorTypesListCall) PageToken(pageToken string) *AcceleratorTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AcceleratorTypesListCall) Fields(s ...googleapi.Field) *AcceleratorTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AcceleratorTypesListCall) IfNoneMatch(entityTag string) *AcceleratorTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AcceleratorTypesListCall) Context(ctx context.Context) *AcceleratorTypesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AcceleratorTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AcceleratorTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/acceleratorTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.acceleratorTypes.list" call.
// Exactly one of *AcceleratorTypeList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AcceleratorTypeList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AcceleratorTypesListCall) Do(opts ...googleapi.CallOption) (*AcceleratorTypeList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AcceleratorTypeList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of accelerator types available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.acceleratorTypes.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/acceleratorTypes",
	//   "response": {
	//     "$ref": "AcceleratorTypeList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AcceleratorTypesListCall) Pages(ctx context.Context, f func(*AcceleratorTypeList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.addresses.aggregatedList":

type AddressesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of addresses. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/addresses/aggregatedList
func (r *AddressesService) AggregatedList(project string) *AddressesAggregatedListCall {
	c := &AddressesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *AddressesAggregatedListCall) Filter(filter string) *AddressesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *AddressesAggregatedListCall) MaxResults(maxResults int64) *AddressesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *AddressesAggregatedListCall) OrderBy(orderBy string) *AddressesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *AddressesAggregatedListCall) PageToken(pageToken string) *AddressesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AddressesAggregatedListCall) Fields(s ...googleapi.Field) *AddressesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AddressesAggregatedListCall) IfNoneMatch(entityTag string) *AddressesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AddressesAggregatedListCall) Context(ctx context.Context) *AddressesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AddressesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AddressesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/addresses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.addresses.aggregatedList" call.
// Exactly one of *AddressAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AddressAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AddressesAggregatedListCall) Do(opts ...googleapi.CallOption) (*AddressAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AddressAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of addresses. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.addresses.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/addresses",
	//   "response": {
	//     "$ref": "AddressAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AddressesAggregatedListCall) Pages(ctx context.Context, f func(*AddressAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.addresses.delete":

type AddressesDeleteCall struct {
	s          *Service
	project    string
	region     string
	address    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified address resource. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/addresses/delete
func (r *AddressesService) Delete(project string, region string, address string) *AddressesDeleteCall {
	c := &AddressesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.address = address
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *AddressesDeleteCall) RequestId(requestId string) *AddressesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AddressesDeleteCall) Fields(s ...googleapi.Field) *AddressesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AddressesDeleteCall) Context(ctx context.Context) *AddressesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AddressesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AddressesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses/{address}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"address": c.address,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.addresses.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AddressesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified address resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.addresses.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "address"
	//   ],
	//   "parameters": {
	//     "address": {
	//       "description": "Name of the address resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/addresses/{address}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.addresses.get":

type AddressesGetCall struct {
	s            *Service
	project      string
	region       string
	address      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified address resource. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/addresses/get
func (r *AddressesService) Get(project string, region string, address string) *AddressesGetCall {
	c := &AddressesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.address = address
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AddressesGetCall) Fields(s ...googleapi.Field) *AddressesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AddressesGetCall) IfNoneMatch(entityTag string) *AddressesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AddressesGetCall) Context(ctx context.Context) *AddressesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AddressesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AddressesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses/{address}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"address": c.address,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.addresses.get" call.
// Exactly one of *Address or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Address.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AddressesGetCall) Do(opts ...googleapi.CallOption) (*Address, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Address{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified address resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.addresses.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "address"
	//   ],
	//   "parameters": {
	//     "address": {
	//       "description": "Name of the address resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/addresses/{address}",
	//   "response": {
	//     "$ref": "Address"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.addresses.insert":

type AddressesInsertCall struct {
	s          *Service
	project    string
	region     string
	address    *Address
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates an address resource in the specified project by using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/addresses/insert
func (r *AddressesService) Insert(project string, region string, address *Address) *AddressesInsertCall {
	c := &AddressesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.address = address
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *AddressesInsertCall) RequestId(requestId string) *AddressesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AddressesInsertCall) Fields(s ...googleapi.Field) *AddressesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AddressesInsertCall) Context(ctx context.Context) *AddressesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AddressesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AddressesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.address)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.addresses.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AddressesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an address resource in the specified project by using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.addresses.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/addresses",
	//   "request": {
	//     "$ref": "Address"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.addresses.list":

type AddressesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of addresses contained within the specified
// region. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/addresses/list
func (r *AddressesService) List(project string, region string) *AddressesListCall {
	c := &AddressesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *AddressesListCall) Filter(filter string) *AddressesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *AddressesListCall) MaxResults(maxResults int64) *AddressesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *AddressesListCall) OrderBy(orderBy string) *AddressesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *AddressesListCall) PageToken(pageToken string) *AddressesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AddressesListCall) Fields(s ...googleapi.Field) *AddressesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AddressesListCall) IfNoneMatch(entityTag string) *AddressesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AddressesListCall) Context(ctx context.Context) *AddressesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AddressesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AddressesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.addresses.list" call.
// Exactly one of *AddressList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AddressList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AddressesListCall) Do(opts ...googleapi.CallOption) (*AddressList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AddressList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of addresses contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.addresses.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/addresses",
	//   "response": {
	//     "$ref": "AddressList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AddressesListCall) Pages(ctx context.Context, f func(*AddressList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.autoscalers.aggregatedList":

type AutoscalersAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of autoscalers. (==
// suppress_warning http-rest-shadowed ==)
func (r *AutoscalersService) AggregatedList(project string) *AutoscalersAggregatedListCall {
	c := &AutoscalersAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *AutoscalersAggregatedListCall) Filter(filter string) *AutoscalersAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *AutoscalersAggregatedListCall) MaxResults(maxResults int64) *AutoscalersAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *AutoscalersAggregatedListCall) OrderBy(orderBy string) *AutoscalersAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *AutoscalersAggregatedListCall) PageToken(pageToken string) *AutoscalersAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AutoscalersAggregatedListCall) Fields(s ...googleapi.Field) *AutoscalersAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AutoscalersAggregatedListCall) IfNoneMatch(entityTag string) *AutoscalersAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AutoscalersAggregatedListCall) Context(ctx context.Context) *AutoscalersAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AutoscalersAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AutoscalersAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.autoscalers.aggregatedList" call.
// Exactly one of *AutoscalerAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *AutoscalerAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AutoscalersAggregatedListCall) Do(opts ...googleapi.CallOption) (*AutoscalerAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AutoscalerAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of autoscalers. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.autoscalers.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/autoscalers",
	//   "response": {
	//     "$ref": "AutoscalerAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AutoscalersAggregatedListCall) Pages(ctx context.Context, f func(*AutoscalerAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.autoscalers.delete":

type AutoscalersDeleteCall struct {
	s          *Service
	project    string
	zone       string
	autoscaler string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified autoscaler. (== suppress_warning
// http-rest-shadowed ==)
func (r *AutoscalersService) Delete(project string, zone string, autoscaler string) *AutoscalersDeleteCall {
	c := &AutoscalersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.autoscaler = autoscaler
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *AutoscalersDeleteCall) RequestId(requestId string) *AutoscalersDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AutoscalersDeleteCall) Fields(s ...googleapi.Field) *AutoscalersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AutoscalersDeleteCall) Context(ctx context.Context) *AutoscalersDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AutoscalersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AutoscalersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/autoscalers/{autoscaler}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"zone":       c.zone,
		"autoscaler": c.autoscaler,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.autoscalers.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AutoscalersDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified autoscaler. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.autoscalers.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "autoscaler"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/autoscalers/{autoscaler}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.autoscalers.get":

type AutoscalersGetCall struct {
	s            *Service
	project      string
	zone         string
	autoscaler   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified autoscaler resource. Gets a list of
// available autoscalers by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *AutoscalersService) Get(project string, zone string, autoscaler string) *AutoscalersGetCall {
	c := &AutoscalersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.autoscaler = autoscaler
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AutoscalersGetCall) Fields(s ...googleapi.Field) *AutoscalersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AutoscalersGetCall) IfNoneMatch(entityTag string) *AutoscalersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AutoscalersGetCall) Context(ctx context.Context) *AutoscalersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AutoscalersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AutoscalersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/autoscalers/{autoscaler}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"zone":       c.zone,
		"autoscaler": c.autoscaler,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.autoscalers.get" call.
// Exactly one of *Autoscaler or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Autoscaler.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AutoscalersGetCall) Do(opts ...googleapi.CallOption) (*Autoscaler, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Autoscaler{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified autoscaler resource. Gets a list of available autoscalers by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.autoscalers.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "autoscaler"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/autoscalers/{autoscaler}",
	//   "response": {
	//     "$ref": "Autoscaler"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.autoscalers.insert":

type AutoscalersInsertCall struct {
	s          *Service
	project    string
	zone       string
	autoscaler *Autoscaler
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates an autoscaler in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *AutoscalersService) Insert(project string, zone string, autoscaler *Autoscaler) *AutoscalersInsertCall {
	c := &AutoscalersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.autoscaler = autoscaler
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *AutoscalersInsertCall) RequestId(requestId string) *AutoscalersInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AutoscalersInsertCall) Fields(s ...googleapi.Field) *AutoscalersInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AutoscalersInsertCall) Context(ctx context.Context) *AutoscalersInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AutoscalersInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AutoscalersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.autoscaler)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.autoscalers.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AutoscalersInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an autoscaler in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.autoscalers.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/autoscalers",
	//   "request": {
	//     "$ref": "Autoscaler"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.autoscalers.list":

type AutoscalersListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of autoscalers contained within the specified
// zone. (== suppress_warning http-rest-shadowed ==)
func (r *AutoscalersService) List(project string, zone string) *AutoscalersListCall {
	c := &AutoscalersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *AutoscalersListCall) Filter(filter string) *AutoscalersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *AutoscalersListCall) MaxResults(maxResults int64) *AutoscalersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *AutoscalersListCall) OrderBy(orderBy string) *AutoscalersListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *AutoscalersListCall) PageToken(pageToken string) *AutoscalersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AutoscalersListCall) Fields(s ...googleapi.Field) *AutoscalersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AutoscalersListCall) IfNoneMatch(entityTag string) *AutoscalersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AutoscalersListCall) Context(ctx context.Context) *AutoscalersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AutoscalersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AutoscalersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.autoscalers.list" call.
// Exactly one of *AutoscalerList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AutoscalerList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AutoscalersListCall) Do(opts ...googleapi.CallOption) (*AutoscalerList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AutoscalerList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of autoscalers contained within the specified zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.autoscalers.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/autoscalers",
	//   "response": {
	//     "$ref": "AutoscalerList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AutoscalersListCall) Pages(ctx context.Context, f func(*AutoscalerList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.autoscalers.patch":

type AutoscalersPatchCall struct {
	s          *Service
	project    string
	zone       string
	autoscaler *Autoscaler
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an autoscaler in the specified project using the data
// included in the request. This method supports PATCH semantics and
// uses the JSON merge patch format and processing rules. (==
// suppress_warning http-rest-shadowed ==)
func (r *AutoscalersService) Patch(project string, zone string, autoscaler *Autoscaler) *AutoscalersPatchCall {
	c := &AutoscalersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.autoscaler = autoscaler
	return c
}

// Autoscaler sets the optional parameter "autoscaler": Name of the
// autoscaler to patch.
func (c *AutoscalersPatchCall) Autoscaler(autoscaler string) *AutoscalersPatchCall {
	c.urlParams_.Set("autoscaler", autoscaler)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *AutoscalersPatchCall) RequestId(requestId string) *AutoscalersPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AutoscalersPatchCall) Fields(s ...googleapi.Field) *AutoscalersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AutoscalersPatchCall) Context(ctx context.Context) *AutoscalersPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AutoscalersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AutoscalersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.autoscaler)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.autoscalers.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AutoscalersPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an autoscaler in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.autoscalers.patch",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to patch.",
	//       "location": "query",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/autoscalers",
	//   "request": {
	//     "$ref": "Autoscaler"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.autoscalers.update":

type AutoscalersUpdateCall struct {
	s          *Service
	project    string
	zone       string
	autoscaler *Autoscaler
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an autoscaler in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *AutoscalersService) Update(project string, zone string, autoscaler *Autoscaler) *AutoscalersUpdateCall {
	c := &AutoscalersUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.autoscaler = autoscaler
	return c
}

// Autoscaler sets the optional parameter "autoscaler": Name of the
// autoscaler to update.
func (c *AutoscalersUpdateCall) Autoscaler(autoscaler string) *AutoscalersUpdateCall {
	c.urlParams_.Set("autoscaler", autoscaler)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *AutoscalersUpdateCall) RequestId(requestId string) *AutoscalersUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AutoscalersUpdateCall) Fields(s ...googleapi.Field) *AutoscalersUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AutoscalersUpdateCall) Context(ctx context.Context) *AutoscalersUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AutoscalersUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AutoscalersUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.autoscaler)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.autoscalers.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AutoscalersUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an autoscaler in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.autoscalers.update",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to update.",
	//       "location": "query",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/autoscalers",
	//   "request": {
	//     "$ref": "Autoscaler"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendBuckets.addSignedUrlKey":

type BackendBucketsAddSignedUrlKeyCall struct {
	s             *Service
	project       string
	backendBucket string
	signedurlkey  *SignedUrlKey
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// AddSignedUrlKey: Adds a key for validating requests with signed URLs
// for this backend bucket. (== suppress_warning http-rest-shadowed ==)
func (r *BackendBucketsService) AddSignedUrlKey(project string, backendBucket string, signedurlkey *SignedUrlKey) *BackendBucketsAddSignedUrlKeyCall {
	c := &BackendBucketsAddSignedUrlKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendBucket = backendBucket
	c.signedurlkey = signedurlkey
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendBucketsAddSignedUrlKeyCall) RequestId(requestId string) *BackendBucketsAddSignedUrlKeyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsAddSignedUrlKeyCall) Fields(s ...googleapi.Field) *BackendBucketsAddSignedUrlKeyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsAddSignedUrlKeyCall) Context(ctx context.Context) *BackendBucketsAddSignedUrlKeyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsAddSignedUrlKeyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsAddSignedUrlKeyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.signedurlkey)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets/{backendBucket}/addSignedUrlKey")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"backendBucket": c.backendBucket,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.addSignedUrlKey" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendBucketsAddSignedUrlKeyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds a key for validating requests with signed URLs for this backend bucket. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendBuckets.addSignedUrlKey",
	//   "parameterOrder": [
	//     "project",
	//     "backendBucket"
	//   ],
	//   "parameters": {
	//     "backendBucket": {
	//       "description": "Name of the BackendBucket resource to which the Signed URL Key should be added. The name should conform to RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets/{backendBucket}/addSignedUrlKey",
	//   "request": {
	//     "$ref": "SignedUrlKey"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendBuckets.delete":

type BackendBucketsDeleteCall struct {
	s             *Service
	project       string
	backendBucket string
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Delete: Deletes the specified BackendBucket resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *BackendBucketsService) Delete(project string, backendBucket string) *BackendBucketsDeleteCall {
	c := &BackendBucketsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendBucket = backendBucket
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendBucketsDeleteCall) RequestId(requestId string) *BackendBucketsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsDeleteCall) Fields(s ...googleapi.Field) *BackendBucketsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsDeleteCall) Context(ctx context.Context) *BackendBucketsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets/{backendBucket}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"backendBucket": c.backendBucket,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendBucketsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified BackendBucket resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.backendBuckets.delete",
	//   "parameterOrder": [
	//     "project",
	//     "backendBucket"
	//   ],
	//   "parameters": {
	//     "backendBucket": {
	//       "description": "Name of the BackendBucket resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets/{backendBucket}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendBuckets.deleteSignedUrlKey":

type BackendBucketsDeleteSignedUrlKeyCall struct {
	s             *Service
	project       string
	backendBucket string
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// DeleteSignedUrlKey: Deletes a key for validating requests with signed
// URLs for this backend bucket. (== suppress_warning http-rest-shadowed
// ==)
func (r *BackendBucketsService) DeleteSignedUrlKey(project string, backendBucket string, keyName string) *BackendBucketsDeleteSignedUrlKeyCall {
	c := &BackendBucketsDeleteSignedUrlKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendBucket = backendBucket
	c.urlParams_.Set("keyName", keyName)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendBucketsDeleteSignedUrlKeyCall) RequestId(requestId string) *BackendBucketsDeleteSignedUrlKeyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsDeleteSignedUrlKeyCall) Fields(s ...googleapi.Field) *BackendBucketsDeleteSignedUrlKeyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsDeleteSignedUrlKeyCall) Context(ctx context.Context) *BackendBucketsDeleteSignedUrlKeyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsDeleteSignedUrlKeyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsDeleteSignedUrlKeyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets/{backendBucket}/deleteSignedUrlKey")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"backendBucket": c.backendBucket,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.deleteSignedUrlKey" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendBucketsDeleteSignedUrlKeyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a key for validating requests with signed URLs for this backend bucket. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendBuckets.deleteSignedUrlKey",
	//   "parameterOrder": [
	//     "project",
	//     "backendBucket",
	//     "keyName"
	//   ],
	//   "parameters": {
	//     "backendBucket": {
	//       "description": "Name of the BackendBucket resource to which the Signed URL Key should be added. The name should conform to RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "keyName": {
	//       "description": "The name of the Signed URL Key to delete.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets/{backendBucket}/deleteSignedUrlKey",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendBuckets.get":

type BackendBucketsGetCall struct {
	s             *Service
	project       string
	backendBucket string
	urlParams_    gensupport.URLParams
	ifNoneMatch_  string
	ctx_          context.Context
	header_       http.Header
}

// Get: Returns the specified BackendBucket resource. Gets a list of
// available backend buckets by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *BackendBucketsService) Get(project string, backendBucket string) *BackendBucketsGetCall {
	c := &BackendBucketsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendBucket = backendBucket
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsGetCall) Fields(s ...googleapi.Field) *BackendBucketsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BackendBucketsGetCall) IfNoneMatch(entityTag string) *BackendBucketsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsGetCall) Context(ctx context.Context) *BackendBucketsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets/{backendBucket}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"backendBucket": c.backendBucket,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.get" call.
// Exactly one of *BackendBucket or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *BackendBucket.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BackendBucketsGetCall) Do(opts ...googleapi.CallOption) (*BackendBucket, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendBucket{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified BackendBucket resource. Gets a list of available backend buckets by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.backendBuckets.get",
	//   "parameterOrder": [
	//     "project",
	//     "backendBucket"
	//   ],
	//   "parameters": {
	//     "backendBucket": {
	//       "description": "Name of the BackendBucket resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets/{backendBucket}",
	//   "response": {
	//     "$ref": "BackendBucket"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.backendBuckets.insert":

type BackendBucketsInsertCall struct {
	s             *Service
	project       string
	backendbucket *BackendBucket
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Creates a BackendBucket resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *BackendBucketsService) Insert(project string, backendbucket *BackendBucket) *BackendBucketsInsertCall {
	c := &BackendBucketsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendbucket = backendbucket
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendBucketsInsertCall) RequestId(requestId string) *BackendBucketsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsInsertCall) Fields(s ...googleapi.Field) *BackendBucketsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsInsertCall) Context(ctx context.Context) *BackendBucketsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendbucket)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendBucketsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a BackendBucket resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendBuckets.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets",
	//   "request": {
	//     "$ref": "BackendBucket"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendBuckets.list":

type BackendBucketsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of BackendBucket resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *BackendBucketsService) List(project string) *BackendBucketsListCall {
	c := &BackendBucketsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *BackendBucketsListCall) Filter(filter string) *BackendBucketsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *BackendBucketsListCall) MaxResults(maxResults int64) *BackendBucketsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *BackendBucketsListCall) OrderBy(orderBy string) *BackendBucketsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *BackendBucketsListCall) PageToken(pageToken string) *BackendBucketsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsListCall) Fields(s ...googleapi.Field) *BackendBucketsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BackendBucketsListCall) IfNoneMatch(entityTag string) *BackendBucketsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsListCall) Context(ctx context.Context) *BackendBucketsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.list" call.
// Exactly one of *BackendBucketList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BackendBucketList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BackendBucketsListCall) Do(opts ...googleapi.CallOption) (*BackendBucketList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendBucketList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of BackendBucket resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.backendBuckets.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets",
	//   "response": {
	//     "$ref": "BackendBucketList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *BackendBucketsListCall) Pages(ctx context.Context, f func(*BackendBucketList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.backendBuckets.patch":

type BackendBucketsPatchCall struct {
	s             *Service
	project       string
	backendBucket string
	backendbucket *BackendBucket
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Patch: Updates the specified BackendBucket resource with the data
// included in the request. This method supports PATCH semantics and
// uses the JSON merge patch format and processing rules. (==
// suppress_warning http-rest-shadowed ==)
func (r *BackendBucketsService) Patch(project string, backendBucket string, backendbucket *BackendBucket) *BackendBucketsPatchCall {
	c := &BackendBucketsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendBucket = backendBucket
	c.backendbucket = backendbucket
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendBucketsPatchCall) RequestId(requestId string) *BackendBucketsPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsPatchCall) Fields(s ...googleapi.Field) *BackendBucketsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsPatchCall) Context(ctx context.Context) *BackendBucketsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendbucket)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets/{backendBucket}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"backendBucket": c.backendBucket,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendBucketsPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified BackendBucket resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.backendBuckets.patch",
	//   "parameterOrder": [
	//     "project",
	//     "backendBucket"
	//   ],
	//   "parameters": {
	//     "backendBucket": {
	//       "description": "Name of the BackendBucket resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets/{backendBucket}",
	//   "request": {
	//     "$ref": "BackendBucket"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendBuckets.update":

type BackendBucketsUpdateCall struct {
	s             *Service
	project       string
	backendBucket string
	backendbucket *BackendBucket
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates the specified BackendBucket resource with the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *BackendBucketsService) Update(project string, backendBucket string, backendbucket *BackendBucket) *BackendBucketsUpdateCall {
	c := &BackendBucketsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendBucket = backendBucket
	c.backendbucket = backendbucket
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendBucketsUpdateCall) RequestId(requestId string) *BackendBucketsUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendBucketsUpdateCall) Fields(s ...googleapi.Field) *BackendBucketsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendBucketsUpdateCall) Context(ctx context.Context) *BackendBucketsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendBucketsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendBucketsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendbucket)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendBuckets/{backendBucket}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"backendBucket": c.backendBucket,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendBuckets.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendBucketsUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified BackendBucket resource with the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.backendBuckets.update",
	//   "parameterOrder": [
	//     "project",
	//     "backendBucket"
	//   ],
	//   "parameters": {
	//     "backendBucket": {
	//       "description": "Name of the BackendBucket resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendBuckets/{backendBucket}",
	//   "request": {
	//     "$ref": "BackendBucket"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendServices.addSignedUrlKey":

type BackendServicesAddSignedUrlKeyCall struct {
	s              *Service
	project        string
	backendService string
	signedurlkey   *SignedUrlKey
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// AddSignedUrlKey: Adds a key for validating requests with signed URLs
// for this backend service. (== suppress_warning http-rest-shadowed ==)
func (r *BackendServicesService) AddSignedUrlKey(project string, backendService string, signedurlkey *SignedUrlKey) *BackendServicesAddSignedUrlKeyCall {
	c := &BackendServicesAddSignedUrlKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	c.signedurlkey = signedurlkey
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendServicesAddSignedUrlKeyCall) RequestId(requestId string) *BackendServicesAddSignedUrlKeyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesAddSignedUrlKeyCall) Fields(s ...googleapi.Field) *BackendServicesAddSignedUrlKeyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesAddSignedUrlKeyCall) Context(ctx context.Context) *BackendServicesAddSignedUrlKeyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesAddSignedUrlKeyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesAddSignedUrlKeyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.signedurlkey)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}/addSignedUrlKey")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.addSignedUrlKey" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendServicesAddSignedUrlKeyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds a key for validating requests with signed URLs for this backend service. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendServices.addSignedUrlKey",
	//   "parameterOrder": [
	//     "project",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to which the Signed URL Key should be added. The name should conform to RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}/addSignedUrlKey",
	//   "request": {
	//     "$ref": "SignedUrlKey"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendServices.aggregatedList":

type BackendServicesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of all BackendService resources,
// regional and global, available to the specified project. (==
// suppress_warning http-rest-shadowed ==)
func (r *BackendServicesService) AggregatedList(project string) *BackendServicesAggregatedListCall {
	c := &BackendServicesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *BackendServicesAggregatedListCall) Filter(filter string) *BackendServicesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *BackendServicesAggregatedListCall) MaxResults(maxResults int64) *BackendServicesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *BackendServicesAggregatedListCall) OrderBy(orderBy string) *BackendServicesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *BackendServicesAggregatedListCall) PageToken(pageToken string) *BackendServicesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesAggregatedListCall) Fields(s ...googleapi.Field) *BackendServicesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BackendServicesAggregatedListCall) IfNoneMatch(entityTag string) *BackendServicesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesAggregatedListCall) Context(ctx context.Context) *BackendServicesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/backendServices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.aggregatedList" call.
// Exactly one of *BackendServiceAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BackendServiceAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BackendServicesAggregatedListCall) Do(opts ...googleapi.CallOption) (*BackendServiceAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendServiceAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of all BackendService resources, regional and global, available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.backendServices.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Name of the project scoping this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/backendServices",
	//   "response": {
	//     "$ref": "BackendServiceAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *BackendServicesAggregatedListCall) Pages(ctx context.Context, f func(*BackendServiceAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.backendServices.delete":

type BackendServicesDeleteCall struct {
	s              *Service
	project        string
	backendService string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified BackendService resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/backendServices/delete
func (r *BackendServicesService) Delete(project string, backendService string) *BackendServicesDeleteCall {
	c := &BackendServicesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendServicesDeleteCall) RequestId(requestId string) *BackendServicesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesDeleteCall) Fields(s ...googleapi.Field) *BackendServicesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesDeleteCall) Context(ctx context.Context) *BackendServicesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendServicesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified BackendService resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.backendServices.delete",
	//   "parameterOrder": [
	//     "project",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendServices.deleteSignedUrlKey":

type BackendServicesDeleteSignedUrlKeyCall struct {
	s              *Service
	project        string
	backendService string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// DeleteSignedUrlKey: Deletes a key for validating requests with signed
// URLs for this backend service. (== suppress_warning
// http-rest-shadowed ==)
func (r *BackendServicesService) DeleteSignedUrlKey(project string, backendService string, keyName string) *BackendServicesDeleteSignedUrlKeyCall {
	c := &BackendServicesDeleteSignedUrlKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	c.urlParams_.Set("keyName", keyName)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendServicesDeleteSignedUrlKeyCall) RequestId(requestId string) *BackendServicesDeleteSignedUrlKeyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesDeleteSignedUrlKeyCall) Fields(s ...googleapi.Field) *BackendServicesDeleteSignedUrlKeyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesDeleteSignedUrlKeyCall) Context(ctx context.Context) *BackendServicesDeleteSignedUrlKeyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesDeleteSignedUrlKeyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesDeleteSignedUrlKeyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}/deleteSignedUrlKey")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.deleteSignedUrlKey" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendServicesDeleteSignedUrlKeyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a key for validating requests with signed URLs for this backend service. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendServices.deleteSignedUrlKey",
	//   "parameterOrder": [
	//     "project",
	//     "backendService",
	//     "keyName"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to which the Signed URL Key should be added. The name should conform to RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "keyName": {
	//       "description": "The name of the Signed URL Key to delete.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}/deleteSignedUrlKey",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendServices.get":

type BackendServicesGetCall struct {
	s              *Service
	project        string
	backendService string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified BackendService resource. Gets a list of
// available backend services. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/backendServices/get
func (r *BackendServicesService) Get(project string, backendService string) *BackendServicesGetCall {
	c := &BackendServicesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesGetCall) Fields(s ...googleapi.Field) *BackendServicesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BackendServicesGetCall) IfNoneMatch(entityTag string) *BackendServicesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesGetCall) Context(ctx context.Context) *BackendServicesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.get" call.
// Exactly one of *BackendService or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *BackendService.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BackendServicesGetCall) Do(opts ...googleapi.CallOption) (*BackendService, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendService{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified BackendService resource. Gets a list of available backend services. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.backendServices.get",
	//   "parameterOrder": [
	//     "project",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}",
	//   "response": {
	//     "$ref": "BackendService"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.backendServices.getHealth":

type BackendServicesGetHealthCall struct {
	s                      *Service
	project                string
	backendService         string
	resourcegroupreference *ResourceGroupReference
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// GetHealth: Gets the most recent health check results for this
// BackendService. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/backendServices/getHealth
func (r *BackendServicesService) GetHealth(project string, backendService string, resourcegroupreference *ResourceGroupReference) *BackendServicesGetHealthCall {
	c := &BackendServicesGetHealthCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	c.resourcegroupreference = resourcegroupreference
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesGetHealthCall) Fields(s ...googleapi.Field) *BackendServicesGetHealthCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesGetHealthCall) Context(ctx context.Context) *BackendServicesGetHealthCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesGetHealthCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesGetHealthCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.resourcegroupreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}/getHealth")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.getHealth" call.
// Exactly one of *BackendServiceGroupHealth or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BackendServiceGroupHealth.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BackendServicesGetHealthCall) Do(opts ...googleapi.CallOption) (*BackendServiceGroupHealth, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendServiceGroupHealth{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the most recent health check results for this BackendService. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendServices.getHealth",
	//   "parameterOrder": [
	//     "project",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to which the queried instance belongs.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}/getHealth",
	//   "request": {
	//     "$ref": "ResourceGroupReference"
	//   },
	//   "response": {
	//     "$ref": "BackendServiceGroupHealth"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.backendServices.insert":

type BackendServicesInsertCall struct {
	s              *Service
	project        string
	backendservice *BackendService
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a BackendService resource in the specified project
// using the data included in the request. There are several
// restrictions and guidelines to keep in mind when creating a backend
// service. Read  Restrictions and Guidelines for more information. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/backendServices/insert
func (r *BackendServicesService) Insert(project string, backendservice *BackendService) *BackendServicesInsertCall {
	c := &BackendServicesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendservice = backendservice
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendServicesInsertCall) RequestId(requestId string) *BackendServicesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesInsertCall) Fields(s ...googleapi.Field) *BackendServicesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesInsertCall) Context(ctx context.Context) *BackendServicesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendServicesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a BackendService resource in the specified project using the data included in the request. There are several restrictions and guidelines to keep in mind when creating a backend service. Read  Restrictions and Guidelines for more information. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendServices.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices",
	//   "request": {
	//     "$ref": "BackendService"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendServices.list":

type BackendServicesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of BackendService resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/backendServices/list
func (r *BackendServicesService) List(project string) *BackendServicesListCall {
	c := &BackendServicesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *BackendServicesListCall) Filter(filter string) *BackendServicesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *BackendServicesListCall) MaxResults(maxResults int64) *BackendServicesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *BackendServicesListCall) OrderBy(orderBy string) *BackendServicesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *BackendServicesListCall) PageToken(pageToken string) *BackendServicesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesListCall) Fields(s ...googleapi.Field) *BackendServicesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BackendServicesListCall) IfNoneMatch(entityTag string) *BackendServicesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesListCall) Context(ctx context.Context) *BackendServicesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.list" call.
// Exactly one of *BackendServiceList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BackendServiceList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BackendServicesListCall) Do(opts ...googleapi.CallOption) (*BackendServiceList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendServiceList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of BackendService resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.backendServices.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices",
	//   "response": {
	//     "$ref": "BackendServiceList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *BackendServicesListCall) Pages(ctx context.Context, f func(*BackendServiceList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.backendServices.patch":

type BackendServicesPatchCall struct {
	s              *Service
	project        string
	backendService string
	backendservice *BackendService
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Patch: Patches the specified BackendService resource with the data
// included in the request. There are several restrictions and
// guidelines to keep in mind when updating a backend service. Read
// Restrictions and Guidelines for more information. This method
// supports PATCH semantics and uses the JSON merge patch format and
// processing rules. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/backendServices/patch
func (r *BackendServicesService) Patch(project string, backendService string, backendservice *BackendService) *BackendServicesPatchCall {
	c := &BackendServicesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	c.backendservice = backendservice
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendServicesPatchCall) RequestId(requestId string) *BackendServicesPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesPatchCall) Fields(s ...googleapi.Field) *BackendServicesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesPatchCall) Context(ctx context.Context) *BackendServicesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendServicesPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified BackendService resource with the data included in the request. There are several restrictions and guidelines to keep in mind when updating a backend service. Read  Restrictions and Guidelines for more information. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.backendServices.patch",
	//   "parameterOrder": [
	//     "project",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}",
	//   "request": {
	//     "$ref": "BackendService"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendServices.setSecurityPolicy":

type BackendServicesSetSecurityPolicyCall struct {
	s                       *Service
	project                 string
	backendService          string
	securitypolicyreference *SecurityPolicyReference
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// SetSecurityPolicy: Sets the security policy for the specified backend
// service. (== suppress_warning http-rest-shadowed ==)
func (r *BackendServicesService) SetSecurityPolicy(project string, backendService string, securitypolicyreference *SecurityPolicyReference) *BackendServicesSetSecurityPolicyCall {
	c := &BackendServicesSetSecurityPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	c.securitypolicyreference = securitypolicyreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendServicesSetSecurityPolicyCall) RequestId(requestId string) *BackendServicesSetSecurityPolicyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesSetSecurityPolicyCall) Fields(s ...googleapi.Field) *BackendServicesSetSecurityPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesSetSecurityPolicyCall) Context(ctx context.Context) *BackendServicesSetSecurityPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesSetSecurityPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesSetSecurityPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.securitypolicyreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}/setSecurityPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.setSecurityPolicy" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendServicesSetSecurityPolicyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the security policy for the specified backend service. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.backendServices.setSecurityPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to which the security policy should be set. The name should conform to RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}/setSecurityPolicy",
	//   "request": {
	//     "$ref": "SecurityPolicyReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.backendServices.update":

type BackendServicesUpdateCall struct {
	s              *Service
	project        string
	backendService string
	backendservice *BackendService
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Update: Updates the specified BackendService resource with the data
// included in the request. There are several restrictions and
// guidelines to keep in mind when updating a backend service. Read
// Restrictions and Guidelines for more information. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/backendServices/update
func (r *BackendServicesService) Update(project string, backendService string, backendservice *BackendService) *BackendServicesUpdateCall {
	c := &BackendServicesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.backendService = backendService
	c.backendservice = backendservice
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *BackendServicesUpdateCall) RequestId(requestId string) *BackendServicesUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BackendServicesUpdateCall) Fields(s ...googleapi.Field) *BackendServicesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BackendServicesUpdateCall) Context(ctx context.Context) *BackendServicesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BackendServicesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BackendServicesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.backendServices.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BackendServicesUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified BackendService resource with the data included in the request. There are several restrictions and guidelines to keep in mind when updating a backend service. Read  Restrictions and Guidelines for more information. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.backendServices.update",
	//   "parameterOrder": [
	//     "project",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/backendServices/{backendService}",
	//   "request": {
	//     "$ref": "BackendService"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.diskTypes.aggregatedList":

type DiskTypesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of disk types. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/diskTypes/aggregatedList
func (r *DiskTypesService) AggregatedList(project string) *DiskTypesAggregatedListCall {
	c := &DiskTypesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *DiskTypesAggregatedListCall) Filter(filter string) *DiskTypesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *DiskTypesAggregatedListCall) MaxResults(maxResults int64) *DiskTypesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *DiskTypesAggregatedListCall) OrderBy(orderBy string) *DiskTypesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *DiskTypesAggregatedListCall) PageToken(pageToken string) *DiskTypesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DiskTypesAggregatedListCall) Fields(s ...googleapi.Field) *DiskTypesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DiskTypesAggregatedListCall) IfNoneMatch(entityTag string) *DiskTypesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DiskTypesAggregatedListCall) Context(ctx context.Context) *DiskTypesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DiskTypesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DiskTypesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/diskTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.diskTypes.aggregatedList" call.
// Exactly one of *DiskTypeAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DiskTypeAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DiskTypesAggregatedListCall) Do(opts ...googleapi.CallOption) (*DiskTypeAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DiskTypeAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of disk types. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.diskTypes.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/diskTypes",
	//   "response": {
	//     "$ref": "DiskTypeAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *DiskTypesAggregatedListCall) Pages(ctx context.Context, f func(*DiskTypeAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.diskTypes.get":

type DiskTypesGetCall struct {
	s            *Service
	project      string
	zone         string
	diskType     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified disk type. Gets a list of available disk
// types by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/diskTypes/get
func (r *DiskTypesService) Get(project string, zone string, diskType string) *DiskTypesGetCall {
	c := &DiskTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.diskType = diskType
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DiskTypesGetCall) Fields(s ...googleapi.Field) *DiskTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DiskTypesGetCall) IfNoneMatch(entityTag string) *DiskTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DiskTypesGetCall) Context(ctx context.Context) *DiskTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DiskTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DiskTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/diskTypes/{diskType}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"diskType": c.diskType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.diskTypes.get" call.
// Exactly one of *DiskType or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *DiskType.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DiskTypesGetCall) Do(opts ...googleapi.CallOption) (*DiskType, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DiskType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified disk type. Gets a list of available disk types by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.diskTypes.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "diskType"
	//   ],
	//   "parameters": {
	//     "diskType": {
	//       "description": "Name of the disk type to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/diskTypes/{diskType}",
	//   "response": {
	//     "$ref": "DiskType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.diskTypes.list":

type DiskTypesListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of disk types available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/diskTypes/list
func (r *DiskTypesService) List(project string, zone string) *DiskTypesListCall {
	c := &DiskTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *DiskTypesListCall) Filter(filter string) *DiskTypesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *DiskTypesListCall) MaxResults(maxResults int64) *DiskTypesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *DiskTypesListCall) OrderBy(orderBy string) *DiskTypesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *DiskTypesListCall) PageToken(pageToken string) *DiskTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DiskTypesListCall) Fields(s ...googleapi.Field) *DiskTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DiskTypesListCall) IfNoneMatch(entityTag string) *DiskTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DiskTypesListCall) Context(ctx context.Context) *DiskTypesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DiskTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DiskTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/diskTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.diskTypes.list" call.
// Exactly one of *DiskTypeList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DiskTypeList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DiskTypesListCall) Do(opts ...googleapi.CallOption) (*DiskTypeList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DiskTypeList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of disk types available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.diskTypes.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/diskTypes",
	//   "response": {
	//     "$ref": "DiskTypeList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *DiskTypesListCall) Pages(ctx context.Context, f func(*DiskTypeList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.disks.addResourcePolicies":

type DisksAddResourcePoliciesCall struct {
	s                               *Service
	project                         string
	zone                            string
	disk                            string
	disksaddresourcepoliciesrequest *DisksAddResourcePoliciesRequest
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// AddResourcePolicies: Adds existing resource policies to a disk. You
// can only add one policy which will be applied to this disk for
// scheduling snapshot creation. (== suppress_warning http-rest-shadowed
// ==)
func (r *DisksService) AddResourcePolicies(project string, zone string, disk string, disksaddresourcepoliciesrequest *DisksAddResourcePoliciesRequest) *DisksAddResourcePoliciesCall {
	c := &DisksAddResourcePoliciesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.disk = disk
	c.disksaddresourcepoliciesrequest = disksaddresourcepoliciesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *DisksAddResourcePoliciesCall) RequestId(requestId string) *DisksAddResourcePoliciesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksAddResourcePoliciesCall) Fields(s ...googleapi.Field) *DisksAddResourcePoliciesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksAddResourcePoliciesCall) Context(ctx context.Context) *DisksAddResourcePoliciesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksAddResourcePoliciesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksAddResourcePoliciesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.disksaddresourcepoliciesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}/addResourcePolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.addResourcePolicies" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksAddResourcePoliciesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds existing resource policies to a disk. You can only add one policy which will be applied to this disk for scheduling snapshot creation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.addResourcePolicies",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "The disk name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{disk}/addResourcePolicies",
	//   "request": {
	//     "$ref": "DisksAddResourcePoliciesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.aggregatedList":

type DisksAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of persistent disks. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/disks/aggregatedList
func (r *DisksService) AggregatedList(project string) *DisksAggregatedListCall {
	c := &DisksAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *DisksAggregatedListCall) Filter(filter string) *DisksAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *DisksAggregatedListCall) MaxResults(maxResults int64) *DisksAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *DisksAggregatedListCall) OrderBy(orderBy string) *DisksAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *DisksAggregatedListCall) PageToken(pageToken string) *DisksAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksAggregatedListCall) Fields(s ...googleapi.Field) *DisksAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DisksAggregatedListCall) IfNoneMatch(entityTag string) *DisksAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksAggregatedListCall) Context(ctx context.Context) *DisksAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/disks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.aggregatedList" call.
// Exactly one of *DiskAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DiskAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DisksAggregatedListCall) Do(opts ...googleapi.CallOption) (*DiskAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DiskAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of persistent disks. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.disks.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/disks",
	//   "response": {
	//     "$ref": "DiskAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *DisksAggregatedListCall) Pages(ctx context.Context, f func(*DiskAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.disks.createSnapshot":

type DisksCreateSnapshotCall struct {
	s          *Service
	project    string
	zone       string
	disk       string
	snapshot   *Snapshot
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// CreateSnapshot: Creates a snapshot of a specified persistent disk.
// (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/disks/createSnapshot
func (r *DisksService) CreateSnapshot(project string, zone string, disk string, snapshot *Snapshot) *DisksCreateSnapshotCall {
	c := &DisksCreateSnapshotCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.disk = disk
	c.snapshot = snapshot
	return c
}

// GuestFlush sets the optional parameter "guestFlush": [Input Only]
// Specifies to create an application consistent snapshot by informing
// the OS to prepare for the snapshot process. Currently only supported
// on Windows instances using the Volume Shadow Copy Service (VSS).
func (c *DisksCreateSnapshotCall) GuestFlush(guestFlush bool) *DisksCreateSnapshotCall {
	c.urlParams_.Set("guestFlush", fmt.Sprint(guestFlush))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *DisksCreateSnapshotCall) RequestId(requestId string) *DisksCreateSnapshotCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksCreateSnapshotCall) Fields(s ...googleapi.Field) *DisksCreateSnapshotCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksCreateSnapshotCall) Context(ctx context.Context) *DisksCreateSnapshotCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksCreateSnapshotCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksCreateSnapshotCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.snapshot)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}/createSnapshot")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.createSnapshot" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksCreateSnapshotCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a snapshot of a specified persistent disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.createSnapshot",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "Name of the persistent disk to snapshot.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "guestFlush": {
	//       "description": "[Input Only] Specifies to create an application consistent snapshot by informing the OS to prepare for the snapshot process. Currently only supported on Windows instances using the Volume Shadow Copy Service (VSS).",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{disk}/createSnapshot",
	//   "request": {
	//     "$ref": "Snapshot"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.delete":

type DisksDeleteCall struct {
	s          *Service
	project    string
	zone       string
	disk       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified persistent disk. Deleting a disk
// removes its data permanently and is irreversible. However, deleting a
// disk does not delete any snapshots previously made from the disk. You
// must separately delete snapshots. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/disks/delete
func (r *DisksService) Delete(project string, zone string, disk string) *DisksDeleteCall {
	c := &DisksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.disk = disk
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *DisksDeleteCall) RequestId(requestId string) *DisksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksDeleteCall) Fields(s ...googleapi.Field) *DisksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksDeleteCall) Context(ctx context.Context) *DisksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified persistent disk. Deleting a disk removes its data permanently and is irreversible. However, deleting a disk does not delete any snapshots previously made from the disk. You must separately delete snapshots. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.disks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "Name of the persistent disk to delete.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{disk}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.get":

type DisksGetCall struct {
	s            *Service
	project      string
	zone         string
	disk         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns a specified persistent disk. Gets a list of available
// persistent disks by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/disks/get
func (r *DisksService) Get(project string, zone string, disk string) *DisksGetCall {
	c := &DisksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.disk = disk
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksGetCall) Fields(s ...googleapi.Field) *DisksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DisksGetCall) IfNoneMatch(entityTag string) *DisksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksGetCall) Context(ctx context.Context) *DisksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.get" call.
// Exactly one of *Disk or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Disk.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *DisksGetCall) Do(opts ...googleapi.CallOption) (*Disk, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Disk{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns a specified persistent disk. Gets a list of available persistent disks by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.disks.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "Name of the persistent disk to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{disk}",
	//   "response": {
	//     "$ref": "Disk"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.disks.getIamPolicy":

type DisksGetIamPolicyCall struct {
	s            *Service
	project      string
	zone         string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *DisksService) GetIamPolicy(project string, zone string, resource string) *DisksGetIamPolicyCall {
	c := &DisksGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksGetIamPolicyCall) Fields(s ...googleapi.Field) *DisksGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DisksGetIamPolicyCall) IfNoneMatch(entityTag string) *DisksGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksGetIamPolicyCall) Context(ctx context.Context) *DisksGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *DisksGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.disks.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.disks.insert":

type DisksInsertCall struct {
	s          *Service
	project    string
	zone       string
	disk       *Disk
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a persistent disk in the specified project using the
// data in the request. You can create a disk with a sourceImage, a
// sourceSnapshot, or create an empty 500 GB data disk by omitting all
// properties. You can also create a disk that is larger than the
// default size by specifying the sizeGb property. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/disks/insert
func (r *DisksService) Insert(project string, zone string, disk *Disk) *DisksInsertCall {
	c := &DisksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.disk = disk
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *DisksInsertCall) RequestId(requestId string) *DisksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// SourceImage sets the optional parameter "sourceImage": Source image
// to restore onto a disk.
func (c *DisksInsertCall) SourceImage(sourceImage string) *DisksInsertCall {
	c.urlParams_.Set("sourceImage", sourceImage)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksInsertCall) Fields(s ...googleapi.Field) *DisksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksInsertCall) Context(ctx context.Context) *DisksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.disk)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a persistent disk in the specified project using the data in the request. You can create a disk with a sourceImage, a sourceSnapshot, or create an empty 500 GB data disk by omitting all properties. You can also create a disk that is larger than the default size by specifying the sizeGb property. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sourceImage": {
	//       "description": "Optional. Source image to restore onto a disk.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks",
	//   "request": {
	//     "$ref": "Disk"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.list":

type DisksListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of persistent disks contained within the
// specified zone. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/disks/list
func (r *DisksService) List(project string, zone string) *DisksListCall {
	c := &DisksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *DisksListCall) Filter(filter string) *DisksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *DisksListCall) MaxResults(maxResults int64) *DisksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *DisksListCall) OrderBy(orderBy string) *DisksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *DisksListCall) PageToken(pageToken string) *DisksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksListCall) Fields(s ...googleapi.Field) *DisksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DisksListCall) IfNoneMatch(entityTag string) *DisksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksListCall) Context(ctx context.Context) *DisksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.list" call.
// Exactly one of *DiskList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *DiskList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksListCall) Do(opts ...googleapi.CallOption) (*DiskList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DiskList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of persistent disks contained within the specified zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.disks.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks",
	//   "response": {
	//     "$ref": "DiskList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *DisksListCall) Pages(ctx context.Context, f func(*DiskList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.disks.removeResourcePolicies":

type DisksRemoveResourcePoliciesCall struct {
	s                                  *Service
	project                            string
	zone                               string
	disk                               string
	disksremoveresourcepoliciesrequest *DisksRemoveResourcePoliciesRequest
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// RemoveResourcePolicies: Removes resource policies from a disk. (==
// suppress_warning http-rest-shadowed ==)
func (r *DisksService) RemoveResourcePolicies(project string, zone string, disk string, disksremoveresourcepoliciesrequest *DisksRemoveResourcePoliciesRequest) *DisksRemoveResourcePoliciesCall {
	c := &DisksRemoveResourcePoliciesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.disk = disk
	c.disksremoveresourcepoliciesrequest = disksremoveresourcepoliciesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *DisksRemoveResourcePoliciesCall) RequestId(requestId string) *DisksRemoveResourcePoliciesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksRemoveResourcePoliciesCall) Fields(s ...googleapi.Field) *DisksRemoveResourcePoliciesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksRemoveResourcePoliciesCall) Context(ctx context.Context) *DisksRemoveResourcePoliciesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksRemoveResourcePoliciesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksRemoveResourcePoliciesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.disksremoveresourcepoliciesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}/removeResourcePolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.removeResourcePolicies" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksRemoveResourcePoliciesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Removes resource policies from a disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.removeResourcePolicies",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "The disk name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{disk}/removeResourcePolicies",
	//   "request": {
	//     "$ref": "DisksRemoveResourcePoliciesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.resize":

type DisksResizeCall struct {
	s                  *Service
	project            string
	zone               string
	disk               string
	disksresizerequest *DisksResizeRequest
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Resize: Resizes the specified persistent disk. You can only increase
// the size of the disk. (== suppress_warning http-rest-shadowed ==)
func (r *DisksService) Resize(project string, zone string, disk string, disksresizerequest *DisksResizeRequest) *DisksResizeCall {
	c := &DisksResizeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.disk = disk
	c.disksresizerequest = disksresizerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *DisksResizeCall) RequestId(requestId string) *DisksResizeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksResizeCall) Fields(s ...googleapi.Field) *DisksResizeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksResizeCall) Context(ctx context.Context) *DisksResizeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksResizeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksResizeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.disksresizerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}/resize")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.resize" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksResizeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Resizes the specified persistent disk. You can only increase the size of the disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.resize",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "The name of the persistent disk.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{disk}/resize",
	//   "request": {
	//     "$ref": "DisksResizeRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.setIamPolicy":

type DisksSetIamPolicyCall struct {
	s                    *Service
	project              string
	zone                 string
	resource             string
	zonesetpolicyrequest *ZoneSetPolicyRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *DisksService) SetIamPolicy(project string, zone string, resource string, zonesetpolicyrequest *ZoneSetPolicyRequest) *DisksSetIamPolicyCall {
	c := &DisksSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.zonesetpolicyrequest = zonesetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksSetIamPolicyCall) Fields(s ...googleapi.Field) *DisksSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksSetIamPolicyCall) Context(ctx context.Context) *DisksSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.zonesetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *DisksSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "ZoneSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.setLabels":

type DisksSetLabelsCall struct {
	s                    *Service
	project              string
	zone                 string
	resource             string
	zonesetlabelsrequest *ZoneSetLabelsRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// SetLabels: Sets the labels on a disk. To learn more about labels,
// read the Labeling Resources documentation. (== suppress_warning
// http-rest-shadowed ==)
func (r *DisksService) SetLabels(project string, zone string, resource string, zonesetlabelsrequest *ZoneSetLabelsRequest) *DisksSetLabelsCall {
	c := &DisksSetLabelsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.zonesetlabelsrequest = zonesetlabelsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *DisksSetLabelsCall) RequestId(requestId string) *DisksSetLabelsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksSetLabelsCall) Fields(s ...googleapi.Field) *DisksSetLabelsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksSetLabelsCall) Context(ctx context.Context) *DisksSetLabelsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksSetLabelsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksSetLabelsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.zonesetlabelsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{resource}/setLabels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.setLabels" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DisksSetLabelsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the labels on a disk. To learn more about labels, read the Labeling Resources documentation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.setLabels",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{resource}/setLabels",
	//   "request": {
	//     "$ref": "ZoneSetLabelsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.disks.testIamPermissions":

type DisksTestIamPermissionsCall struct {
	s                      *Service
	project                string
	zone                   string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *DisksService) TestIamPermissions(project string, zone string, resource string, testpermissionsrequest *TestPermissionsRequest) *DisksTestIamPermissionsCall {
	c := &DisksTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DisksTestIamPermissionsCall) Fields(s ...googleapi.Field) *DisksTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DisksTestIamPermissionsCall) Context(ctx context.Context) *DisksTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DisksTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DisksTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.disks.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DisksTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.disks.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/disks/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.externalVpnGateways.delete":

type ExternalVpnGatewaysDeleteCall struct {
	s                  *Service
	project            string
	externalVpnGateway string
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Delete: Deletes the specified externalVpnGateway. (==
// suppress_warning http-rest-shadowed ==)
func (r *ExternalVpnGatewaysService) Delete(project string, externalVpnGateway string) *ExternalVpnGatewaysDeleteCall {
	c := &ExternalVpnGatewaysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.externalVpnGateway = externalVpnGateway
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ExternalVpnGatewaysDeleteCall) RequestId(requestId string) *ExternalVpnGatewaysDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ExternalVpnGatewaysDeleteCall) Fields(s ...googleapi.Field) *ExternalVpnGatewaysDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ExternalVpnGatewaysDeleteCall) Context(ctx context.Context) *ExternalVpnGatewaysDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ExternalVpnGatewaysDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ExternalVpnGatewaysDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/externalVpnGateways/{externalVpnGateway}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":            c.project,
		"externalVpnGateway": c.externalVpnGateway,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.externalVpnGateways.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ExternalVpnGatewaysDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified externalVpnGateway. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.externalVpnGateways.delete",
	//   "parameterOrder": [
	//     "project",
	//     "externalVpnGateway"
	//   ],
	//   "parameters": {
	//     "externalVpnGateway": {
	//       "description": "Name of the externalVpnGateways to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/externalVpnGateways/{externalVpnGateway}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.externalVpnGateways.get":

type ExternalVpnGatewaysGetCall struct {
	s                  *Service
	project            string
	externalVpnGateway string
	urlParams_         gensupport.URLParams
	ifNoneMatch_       string
	ctx_               context.Context
	header_            http.Header
}

// Get: Returns the specified externalVpnGateway. Get a list of
// available externalVpnGateways by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *ExternalVpnGatewaysService) Get(project string, externalVpnGateway string) *ExternalVpnGatewaysGetCall {
	c := &ExternalVpnGatewaysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.externalVpnGateway = externalVpnGateway
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ExternalVpnGatewaysGetCall) Fields(s ...googleapi.Field) *ExternalVpnGatewaysGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ExternalVpnGatewaysGetCall) IfNoneMatch(entityTag string) *ExternalVpnGatewaysGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ExternalVpnGatewaysGetCall) Context(ctx context.Context) *ExternalVpnGatewaysGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ExternalVpnGatewaysGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ExternalVpnGatewaysGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/externalVpnGateways/{externalVpnGateway}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":            c.project,
		"externalVpnGateway": c.externalVpnGateway,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.externalVpnGateways.get" call.
// Exactly one of *ExternalVpnGateway or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ExternalVpnGateway.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ExternalVpnGatewaysGetCall) Do(opts ...googleapi.CallOption) (*ExternalVpnGateway, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ExternalVpnGateway{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified externalVpnGateway. Get a list of available externalVpnGateways by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.externalVpnGateways.get",
	//   "parameterOrder": [
	//     "project",
	//     "externalVpnGateway"
	//   ],
	//   "parameters": {
	//     "externalVpnGateway": {
	//       "description": "Name of the externalVpnGateway to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/externalVpnGateways/{externalVpnGateway}",
	//   "response": {
	//     "$ref": "ExternalVpnGateway"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.externalVpnGateways.insert":

type ExternalVpnGatewaysInsertCall struct {
	s                  *Service
	project            string
	externalvpngateway *ExternalVpnGateway
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Insert: Creates a ExternalVpnGateway in the specified project using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *ExternalVpnGatewaysService) Insert(project string, externalvpngateway *ExternalVpnGateway) *ExternalVpnGatewaysInsertCall {
	c := &ExternalVpnGatewaysInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.externalvpngateway = externalvpngateway
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ExternalVpnGatewaysInsertCall) RequestId(requestId string) *ExternalVpnGatewaysInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ExternalVpnGatewaysInsertCall) Fields(s ...googleapi.Field) *ExternalVpnGatewaysInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ExternalVpnGatewaysInsertCall) Context(ctx context.Context) *ExternalVpnGatewaysInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ExternalVpnGatewaysInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ExternalVpnGatewaysInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.externalvpngateway)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/externalVpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.externalVpnGateways.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ExternalVpnGatewaysInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a ExternalVpnGateway in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.externalVpnGateways.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/externalVpnGateways",
	//   "request": {
	//     "$ref": "ExternalVpnGateway"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.externalVpnGateways.list":

type ExternalVpnGatewaysListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of ExternalVpnGateway available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *ExternalVpnGatewaysService) List(project string) *ExternalVpnGatewaysListCall {
	c := &ExternalVpnGatewaysListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ExternalVpnGatewaysListCall) Filter(filter string) *ExternalVpnGatewaysListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ExternalVpnGatewaysListCall) MaxResults(maxResults int64) *ExternalVpnGatewaysListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ExternalVpnGatewaysListCall) OrderBy(orderBy string) *ExternalVpnGatewaysListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ExternalVpnGatewaysListCall) PageToken(pageToken string) *ExternalVpnGatewaysListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ExternalVpnGatewaysListCall) Fields(s ...googleapi.Field) *ExternalVpnGatewaysListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ExternalVpnGatewaysListCall) IfNoneMatch(entityTag string) *ExternalVpnGatewaysListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ExternalVpnGatewaysListCall) Context(ctx context.Context) *ExternalVpnGatewaysListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ExternalVpnGatewaysListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ExternalVpnGatewaysListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/externalVpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.externalVpnGateways.list" call.
// Exactly one of *ExternalVpnGatewayList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ExternalVpnGatewayList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ExternalVpnGatewaysListCall) Do(opts ...googleapi.CallOption) (*ExternalVpnGatewayList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ExternalVpnGatewayList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of ExternalVpnGateway available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.externalVpnGateways.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/externalVpnGateways",
	//   "response": {
	//     "$ref": "ExternalVpnGatewayList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ExternalVpnGatewaysListCall) Pages(ctx context.Context, f func(*ExternalVpnGatewayList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.externalVpnGateways.setLabels":

type ExternalVpnGatewaysSetLabelsCall struct {
	s                      *Service
	project                string
	resource               string
	globalsetlabelsrequest *GlobalSetLabelsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetLabels: Sets the labels on an ExternalVpnGateway. To learn more
// about labels, read the Labeling Resources documentation. (==
// suppress_warning http-rest-shadowed ==)
func (r *ExternalVpnGatewaysService) SetLabels(project string, resource string, globalsetlabelsrequest *GlobalSetLabelsRequest) *ExternalVpnGatewaysSetLabelsCall {
	c := &ExternalVpnGatewaysSetLabelsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.globalsetlabelsrequest = globalsetlabelsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ExternalVpnGatewaysSetLabelsCall) Fields(s ...googleapi.Field) *ExternalVpnGatewaysSetLabelsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ExternalVpnGatewaysSetLabelsCall) Context(ctx context.Context) *ExternalVpnGatewaysSetLabelsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ExternalVpnGatewaysSetLabelsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ExternalVpnGatewaysSetLabelsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.globalsetlabelsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/externalVpnGateways/{resource}/setLabels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.externalVpnGateways.setLabels" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ExternalVpnGatewaysSetLabelsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the labels on an ExternalVpnGateway. To learn more about labels, read the Labeling Resources documentation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.externalVpnGateways.setLabels",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/externalVpnGateways/{resource}/setLabels",
	//   "request": {
	//     "$ref": "GlobalSetLabelsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.externalVpnGateways.testIamPermissions":

type ExternalVpnGatewaysTestIamPermissionsCall struct {
	s                      *Service
	project                string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *ExternalVpnGatewaysService) TestIamPermissions(project string, resource string, testpermissionsrequest *TestPermissionsRequest) *ExternalVpnGatewaysTestIamPermissionsCall {
	c := &ExternalVpnGatewaysTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ExternalVpnGatewaysTestIamPermissionsCall) Fields(s ...googleapi.Field) *ExternalVpnGatewaysTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ExternalVpnGatewaysTestIamPermissionsCall) Context(ctx context.Context) *ExternalVpnGatewaysTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ExternalVpnGatewaysTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ExternalVpnGatewaysTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/externalVpnGateways/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.externalVpnGateways.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ExternalVpnGatewaysTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.externalVpnGateways.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/externalVpnGateways/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.firewalls.delete":

type FirewallsDeleteCall struct {
	s          *Service
	project    string
	firewall   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified firewall. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/firewalls/delete
func (r *FirewallsService) Delete(project string, firewall string) *FirewallsDeleteCall {
	c := &FirewallsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.firewall = firewall
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *FirewallsDeleteCall) RequestId(requestId string) *FirewallsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FirewallsDeleteCall) Fields(s ...googleapi.Field) *FirewallsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FirewallsDeleteCall) Context(ctx context.Context) *FirewallsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FirewallsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirewallsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"firewall": c.firewall,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.firewalls.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FirewallsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified firewall. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.firewalls.delete",
	//   "parameterOrder": [
	//     "project",
	//     "firewall"
	//   ],
	//   "parameters": {
	//     "firewall": {
	//       "description": "Name of the firewall rule to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/firewalls/{firewall}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.firewalls.get":

type FirewallsGetCall struct {
	s            *Service
	project      string
	firewall     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified firewall. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/firewalls/get
func (r *FirewallsService) Get(project string, firewall string) *FirewallsGetCall {
	c := &FirewallsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.firewall = firewall
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FirewallsGetCall) Fields(s ...googleapi.Field) *FirewallsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FirewallsGetCall) IfNoneMatch(entityTag string) *FirewallsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FirewallsGetCall) Context(ctx context.Context) *FirewallsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FirewallsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirewallsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"firewall": c.firewall,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.firewalls.get" call.
// Exactly one of *Firewall or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Firewall.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FirewallsGetCall) Do(opts ...googleapi.CallOption) (*Firewall, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Firewall{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified firewall. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.firewalls.get",
	//   "parameterOrder": [
	//     "project",
	//     "firewall"
	//   ],
	//   "parameters": {
	//     "firewall": {
	//       "description": "Name of the firewall rule to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/firewalls/{firewall}",
	//   "response": {
	//     "$ref": "Firewall"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.firewalls.insert":

type FirewallsInsertCall struct {
	s          *Service
	project    string
	firewall   *Firewall
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a firewall rule in the specified project using the
// data included in the request. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/firewalls/insert
func (r *FirewallsService) Insert(project string, firewall *Firewall) *FirewallsInsertCall {
	c := &FirewallsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.firewall = firewall
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *FirewallsInsertCall) RequestId(requestId string) *FirewallsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FirewallsInsertCall) Fields(s ...googleapi.Field) *FirewallsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FirewallsInsertCall) Context(ctx context.Context) *FirewallsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FirewallsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirewallsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.firewall)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.firewalls.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FirewallsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a firewall rule in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.firewalls.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/firewalls",
	//   "request": {
	//     "$ref": "Firewall"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.firewalls.list":

type FirewallsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of firewall rules available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/firewalls/list
func (r *FirewallsService) List(project string) *FirewallsListCall {
	c := &FirewallsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *FirewallsListCall) Filter(filter string) *FirewallsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *FirewallsListCall) MaxResults(maxResults int64) *FirewallsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *FirewallsListCall) OrderBy(orderBy string) *FirewallsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *FirewallsListCall) PageToken(pageToken string) *FirewallsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FirewallsListCall) Fields(s ...googleapi.Field) *FirewallsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FirewallsListCall) IfNoneMatch(entityTag string) *FirewallsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FirewallsListCall) Context(ctx context.Context) *FirewallsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FirewallsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirewallsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.firewalls.list" call.
// Exactly one of *FirewallList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *FirewallList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FirewallsListCall) Do(opts ...googleapi.CallOption) (*FirewallList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FirewallList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of firewall rules available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.firewalls.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/firewalls",
	//   "response": {
	//     "$ref": "FirewallList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *FirewallsListCall) Pages(ctx context.Context, f func(*FirewallList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.firewalls.patch":

type FirewallsPatchCall struct {
	s          *Service
	project    string
	firewall   string
	firewall2  *Firewall
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates the specified firewall rule with the data included in
// the request. This method supports PATCH semantics and uses the JSON
// merge patch format and processing rules. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/firewalls/patch
func (r *FirewallsService) Patch(project string, firewall string, firewall2 *Firewall) *FirewallsPatchCall {
	c := &FirewallsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.firewall = firewall
	c.firewall2 = firewall2
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *FirewallsPatchCall) RequestId(requestId string) *FirewallsPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FirewallsPatchCall) Fields(s ...googleapi.Field) *FirewallsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FirewallsPatchCall) Context(ctx context.Context) *FirewallsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FirewallsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirewallsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.firewall2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"firewall": c.firewall,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.firewalls.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FirewallsPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified firewall rule with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.firewalls.patch",
	//   "parameterOrder": [
	//     "project",
	//     "firewall"
	//   ],
	//   "parameters": {
	//     "firewall": {
	//       "description": "Name of the firewall rule to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/firewalls/{firewall}",
	//   "request": {
	//     "$ref": "Firewall"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.firewalls.update":

type FirewallsUpdateCall struct {
	s          *Service
	project    string
	firewall   string
	firewall2  *Firewall
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates the specified firewall rule with the data included in
// the request. Note that all fields will be updated if using PUT, even
// fields that are not specified. To update individual fields, please
// use PATCH instead. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/firewalls/update
func (r *FirewallsService) Update(project string, firewall string, firewall2 *Firewall) *FirewallsUpdateCall {
	c := &FirewallsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.firewall = firewall
	c.firewall2 = firewall2
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *FirewallsUpdateCall) RequestId(requestId string) *FirewallsUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FirewallsUpdateCall) Fields(s ...googleapi.Field) *FirewallsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FirewallsUpdateCall) Context(ctx context.Context) *FirewallsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FirewallsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirewallsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.firewall2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"firewall": c.firewall,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.firewalls.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FirewallsUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified firewall rule with the data included in the request. Note that all fields will be updated if using PUT, even fields that are not specified. To update individual fields, please use PATCH instead. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.firewalls.update",
	//   "parameterOrder": [
	//     "project",
	//     "firewall"
	//   ],
	//   "parameters": {
	//     "firewall": {
	//       "description": "Name of the firewall rule to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/firewalls/{firewall}",
	//   "request": {
	//     "$ref": "Firewall"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.forwardingRules.aggregatedList":

type ForwardingRulesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of forwarding rules. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/forwardingRules/aggregatedList
func (r *ForwardingRulesService) AggregatedList(project string) *ForwardingRulesAggregatedListCall {
	c := &ForwardingRulesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ForwardingRulesAggregatedListCall) Filter(filter string) *ForwardingRulesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ForwardingRulesAggregatedListCall) MaxResults(maxResults int64) *ForwardingRulesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ForwardingRulesAggregatedListCall) OrderBy(orderBy string) *ForwardingRulesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ForwardingRulesAggregatedListCall) PageToken(pageToken string) *ForwardingRulesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ForwardingRulesAggregatedListCall) Fields(s ...googleapi.Field) *ForwardingRulesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ForwardingRulesAggregatedListCall) IfNoneMatch(entityTag string) *ForwardingRulesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ForwardingRulesAggregatedListCall) Context(ctx context.Context) *ForwardingRulesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ForwardingRulesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ForwardingRulesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/forwardingRules")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.forwardingRules.aggregatedList" call.
// Exactly one of *ForwardingRuleAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ForwardingRuleAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ForwardingRulesAggregatedListCall) Do(opts ...googleapi.CallOption) (*ForwardingRuleAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ForwardingRuleAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of forwarding rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.forwardingRules.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/forwardingRules",
	//   "response": {
	//     "$ref": "ForwardingRuleAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ForwardingRulesAggregatedListCall) Pages(ctx context.Context, f func(*ForwardingRuleAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.forwardingRules.delete":

type ForwardingRulesDeleteCall struct {
	s              *Service
	project        string
	region         string
	forwardingRule string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified ForwardingRule resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/forwardingRules/delete
func (r *ForwardingRulesService) Delete(project string, region string, forwardingRule string) *ForwardingRulesDeleteCall {
	c := &ForwardingRulesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.forwardingRule = forwardingRule
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ForwardingRulesDeleteCall) RequestId(requestId string) *ForwardingRulesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ForwardingRulesDeleteCall) Fields(s ...googleapi.Field) *ForwardingRulesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ForwardingRulesDeleteCall) Context(ctx context.Context) *ForwardingRulesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ForwardingRulesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ForwardingRulesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules/{forwardingRule}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"forwardingRule": c.forwardingRule,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.forwardingRules.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ForwardingRulesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified ForwardingRule resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.forwardingRules.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "forwardingRule"
	//   ],
	//   "parameters": {
	//     "forwardingRule": {
	//       "description": "Name of the ForwardingRule resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.forwardingRules.get":

type ForwardingRulesGetCall struct {
	s              *Service
	project        string
	region         string
	forwardingRule string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified ForwardingRule resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/forwardingRules/get
func (r *ForwardingRulesService) Get(project string, region string, forwardingRule string) *ForwardingRulesGetCall {
	c := &ForwardingRulesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.forwardingRule = forwardingRule
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ForwardingRulesGetCall) Fields(s ...googleapi.Field) *ForwardingRulesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ForwardingRulesGetCall) IfNoneMatch(entityTag string) *ForwardingRulesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ForwardingRulesGetCall) Context(ctx context.Context) *ForwardingRulesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ForwardingRulesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ForwardingRulesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules/{forwardingRule}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"forwardingRule": c.forwardingRule,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.forwardingRules.get" call.
// Exactly one of *ForwardingRule or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ForwardingRule.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ForwardingRulesGetCall) Do(opts ...googleapi.CallOption) (*ForwardingRule, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ForwardingRule{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified ForwardingRule resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.forwardingRules.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "forwardingRule"
	//   ],
	//   "parameters": {
	//     "forwardingRule": {
	//       "description": "Name of the ForwardingRule resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}",
	//   "response": {
	//     "$ref": "ForwardingRule"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.forwardingRules.insert":

type ForwardingRulesInsertCall struct {
	s              *Service
	project        string
	region         string
	forwardingrule *ForwardingRule
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a ForwardingRule resource in the specified project
// and region using the data included in the request. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/forwardingRules/insert
func (r *ForwardingRulesService) Insert(project string, region string, forwardingrule *ForwardingRule) *ForwardingRulesInsertCall {
	c := &ForwardingRulesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.forwardingrule = forwardingrule
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ForwardingRulesInsertCall) RequestId(requestId string) *ForwardingRulesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ForwardingRulesInsertCall) Fields(s ...googleapi.Field) *ForwardingRulesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ForwardingRulesInsertCall) Context(ctx context.Context) *ForwardingRulesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ForwardingRulesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ForwardingRulesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.forwardingrule)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.forwardingRules.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ForwardingRulesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a ForwardingRule resource in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.forwardingRules.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/forwardingRules",
	//   "request": {
	//     "$ref": "ForwardingRule"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.forwardingRules.list":

type ForwardingRulesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of ForwardingRule resources available to the
// specified project and region. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/forwardingRules/list
func (r *ForwardingRulesService) List(project string, region string) *ForwardingRulesListCall {
	c := &ForwardingRulesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ForwardingRulesListCall) Filter(filter string) *ForwardingRulesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ForwardingRulesListCall) MaxResults(maxResults int64) *ForwardingRulesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ForwardingRulesListCall) OrderBy(orderBy string) *ForwardingRulesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ForwardingRulesListCall) PageToken(pageToken string) *ForwardingRulesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ForwardingRulesListCall) Fields(s ...googleapi.Field) *ForwardingRulesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ForwardingRulesListCall) IfNoneMatch(entityTag string) *ForwardingRulesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ForwardingRulesListCall) Context(ctx context.Context) *ForwardingRulesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ForwardingRulesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ForwardingRulesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.forwardingRules.list" call.
// Exactly one of *ForwardingRuleList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ForwardingRuleList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ForwardingRulesListCall) Do(opts ...googleapi.CallOption) (*ForwardingRuleList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ForwardingRuleList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of ForwardingRule resources available to the specified project and region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.forwardingRules.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/forwardingRules",
	//   "response": {
	//     "$ref": "ForwardingRuleList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ForwardingRulesListCall) Pages(ctx context.Context, f func(*ForwardingRuleList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.forwardingRules.setTarget":

type ForwardingRulesSetTargetCall struct {
	s               *Service
	project         string
	region          string
	forwardingRule  string
	targetreference *TargetReference
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// SetTarget: Changes target URL for forwarding rule. The new target
// should be of the same type as the old target. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/forwardingRules/setTarget
func (r *ForwardingRulesService) SetTarget(project string, region string, forwardingRule string, targetreference *TargetReference) *ForwardingRulesSetTargetCall {
	c := &ForwardingRulesSetTargetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.forwardingRule = forwardingRule
	c.targetreference = targetreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ForwardingRulesSetTargetCall) RequestId(requestId string) *ForwardingRulesSetTargetCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ForwardingRulesSetTargetCall) Fields(s ...googleapi.Field) *ForwardingRulesSetTargetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ForwardingRulesSetTargetCall) Context(ctx context.Context) *ForwardingRulesSetTargetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ForwardingRulesSetTargetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ForwardingRulesSetTargetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules/{forwardingRule}/setTarget")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"forwardingRule": c.forwardingRule,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.forwardingRules.setTarget" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ForwardingRulesSetTargetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes target URL for forwarding rule. The new target should be of the same type as the old target. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.forwardingRules.setTarget",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "forwardingRule"
	//   ],
	//   "parameters": {
	//     "forwardingRule": {
	//       "description": "Name of the ForwardingRule resource in which target is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}/setTarget",
	//   "request": {
	//     "$ref": "TargetReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.globalAddresses.delete":

type GlobalAddressesDeleteCall struct {
	s          *Service
	project    string
	address    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified address resource. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalAddresses/delete
func (r *GlobalAddressesService) Delete(project string, address string) *GlobalAddressesDeleteCall {
	c := &GlobalAddressesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.address = address
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *GlobalAddressesDeleteCall) RequestId(requestId string) *GlobalAddressesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalAddressesDeleteCall) Fields(s ...googleapi.Field) *GlobalAddressesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalAddressesDeleteCall) Context(ctx context.Context) *GlobalAddressesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalAddressesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalAddressesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses/{address}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"address": c.address,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalAddresses.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *GlobalAddressesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified address resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.globalAddresses.delete",
	//   "parameterOrder": [
	//     "project",
	//     "address"
	//   ],
	//   "parameters": {
	//     "address": {
	//       "description": "Name of the address resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/addresses/{address}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.globalAddresses.get":

type GlobalAddressesGetCall struct {
	s            *Service
	project      string
	address      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified address resource. Gets a list of available
// addresses by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalAddresses/get
func (r *GlobalAddressesService) Get(project string, address string) *GlobalAddressesGetCall {
	c := &GlobalAddressesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.address = address
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalAddressesGetCall) Fields(s ...googleapi.Field) *GlobalAddressesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GlobalAddressesGetCall) IfNoneMatch(entityTag string) *GlobalAddressesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalAddressesGetCall) Context(ctx context.Context) *GlobalAddressesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalAddressesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalAddressesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses/{address}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"address": c.address,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalAddresses.get" call.
// Exactly one of *Address or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Address.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *GlobalAddressesGetCall) Do(opts ...googleapi.CallOption) (*Address, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Address{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified address resource. Gets a list of available addresses by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.globalAddresses.get",
	//   "parameterOrder": [
	//     "project",
	//     "address"
	//   ],
	//   "parameters": {
	//     "address": {
	//       "description": "Name of the address resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/addresses/{address}",
	//   "response": {
	//     "$ref": "Address"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.globalAddresses.insert":

type GlobalAddressesInsertCall struct {
	s          *Service
	project    string
	address    *Address
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates an address resource in the specified project by using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalAddresses/insert
func (r *GlobalAddressesService) Insert(project string, address *Address) *GlobalAddressesInsertCall {
	c := &GlobalAddressesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.address = address
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *GlobalAddressesInsertCall) RequestId(requestId string) *GlobalAddressesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalAddressesInsertCall) Fields(s ...googleapi.Field) *GlobalAddressesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalAddressesInsertCall) Context(ctx context.Context) *GlobalAddressesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalAddressesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalAddressesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.address)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalAddresses.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *GlobalAddressesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an address resource in the specified project by using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.globalAddresses.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/addresses",
	//   "request": {
	//     "$ref": "Address"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.globalAddresses.list":

type GlobalAddressesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of global addresses. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalAddresses/list
func (r *GlobalAddressesService) List(project string) *GlobalAddressesListCall {
	c := &GlobalAddressesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *GlobalAddressesListCall) Filter(filter string) *GlobalAddressesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *GlobalAddressesListCall) MaxResults(maxResults int64) *GlobalAddressesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *GlobalAddressesListCall) OrderBy(orderBy string) *GlobalAddressesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *GlobalAddressesListCall) PageToken(pageToken string) *GlobalAddressesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalAddressesListCall) Fields(s ...googleapi.Field) *GlobalAddressesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GlobalAddressesListCall) IfNoneMatch(entityTag string) *GlobalAddressesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalAddressesListCall) Context(ctx context.Context) *GlobalAddressesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalAddressesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalAddressesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalAddresses.list" call.
// Exactly one of *AddressList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AddressList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *GlobalAddressesListCall) Do(opts ...googleapi.CallOption) (*AddressList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AddressList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of global addresses. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.globalAddresses.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/addresses",
	//   "response": {
	//     "$ref": "AddressList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *GlobalAddressesListCall) Pages(ctx context.Context, f func(*AddressList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.globalForwardingRules.delete":

type GlobalForwardingRulesDeleteCall struct {
	s              *Service
	project        string
	forwardingRule string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified GlobalForwardingRule resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalForwardingRules/delete
func (r *GlobalForwardingRulesService) Delete(project string, forwardingRule string) *GlobalForwardingRulesDeleteCall {
	c := &GlobalForwardingRulesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.forwardingRule = forwardingRule
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *GlobalForwardingRulesDeleteCall) RequestId(requestId string) *GlobalForwardingRulesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalForwardingRulesDeleteCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalForwardingRulesDeleteCall) Context(ctx context.Context) *GlobalForwardingRulesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalForwardingRulesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalForwardingRulesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules/{forwardingRule}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"forwardingRule": c.forwardingRule,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalForwardingRules.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *GlobalForwardingRulesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified GlobalForwardingRule resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.globalForwardingRules.delete",
	//   "parameterOrder": [
	//     "project",
	//     "forwardingRule"
	//   ],
	//   "parameters": {
	//     "forwardingRule": {
	//       "description": "Name of the ForwardingRule resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/forwardingRules/{forwardingRule}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.globalForwardingRules.get":

type GlobalForwardingRulesGetCall struct {
	s              *Service
	project        string
	forwardingRule string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified GlobalForwardingRule resource. Gets a list
// of available forwarding rules by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalForwardingRules/get
func (r *GlobalForwardingRulesService) Get(project string, forwardingRule string) *GlobalForwardingRulesGetCall {
	c := &GlobalForwardingRulesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.forwardingRule = forwardingRule
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalForwardingRulesGetCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GlobalForwardingRulesGetCall) IfNoneMatch(entityTag string) *GlobalForwardingRulesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalForwardingRulesGetCall) Context(ctx context.Context) *GlobalForwardingRulesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalForwardingRulesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalForwardingRulesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules/{forwardingRule}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"forwardingRule": c.forwardingRule,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalForwardingRules.get" call.
// Exactly one of *ForwardingRule or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ForwardingRule.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *GlobalForwardingRulesGetCall) Do(opts ...googleapi.CallOption) (*ForwardingRule, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ForwardingRule{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified GlobalForwardingRule resource. Gets a list of available forwarding rules by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.globalForwardingRules.get",
	//   "parameterOrder": [
	//     "project",
	//     "forwardingRule"
	//   ],
	//   "parameters": {
	//     "forwardingRule": {
	//       "description": "Name of the ForwardingRule resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/forwardingRules/{forwardingRule}",
	//   "response": {
	//     "$ref": "ForwardingRule"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.globalForwardingRules.insert":

type GlobalForwardingRulesInsertCall struct {
	s              *Service
	project        string
	forwardingrule *ForwardingRule
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a GlobalForwardingRule resource in the specified
// project using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalForwardingRules/insert
func (r *GlobalForwardingRulesService) Insert(project string, forwardingrule *ForwardingRule) *GlobalForwardingRulesInsertCall {
	c := &GlobalForwardingRulesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.forwardingrule = forwardingrule
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *GlobalForwardingRulesInsertCall) RequestId(requestId string) *GlobalForwardingRulesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalForwardingRulesInsertCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalForwardingRulesInsertCall) Context(ctx context.Context) *GlobalForwardingRulesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalForwardingRulesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalForwardingRulesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.forwardingrule)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalForwardingRules.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *GlobalForwardingRulesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a GlobalForwardingRule resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.globalForwardingRules.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/forwardingRules",
	//   "request": {
	//     "$ref": "ForwardingRule"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.globalForwardingRules.list":

type GlobalForwardingRulesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of GlobalForwardingRule resources available to
// the specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalForwardingRules/list
func (r *GlobalForwardingRulesService) List(project string) *GlobalForwardingRulesListCall {
	c := &GlobalForwardingRulesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *GlobalForwardingRulesListCall) Filter(filter string) *GlobalForwardingRulesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *GlobalForwardingRulesListCall) MaxResults(maxResults int64) *GlobalForwardingRulesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *GlobalForwardingRulesListCall) OrderBy(orderBy string) *GlobalForwardingRulesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *GlobalForwardingRulesListCall) PageToken(pageToken string) *GlobalForwardingRulesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalForwardingRulesListCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GlobalForwardingRulesListCall) IfNoneMatch(entityTag string) *GlobalForwardingRulesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalForwardingRulesListCall) Context(ctx context.Context) *GlobalForwardingRulesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalForwardingRulesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalForwardingRulesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalForwardingRules.list" call.
// Exactly one of *ForwardingRuleList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ForwardingRuleList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *GlobalForwardingRulesListCall) Do(opts ...googleapi.CallOption) (*ForwardingRuleList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ForwardingRuleList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of GlobalForwardingRule resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.globalForwardingRules.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/forwardingRules",
	//   "response": {
	//     "$ref": "ForwardingRuleList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *GlobalForwardingRulesListCall) Pages(ctx context.Context, f func(*ForwardingRuleList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.globalForwardingRules.setTarget":

type GlobalForwardingRulesSetTargetCall struct {
	s               *Service
	project         string
	forwardingRule  string
	targetreference *TargetReference
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// SetTarget: Changes target URL for the GlobalForwardingRule resource.
// The new target should be of the same type as the old target. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalForwardingRules/setTarget
func (r *GlobalForwardingRulesService) SetTarget(project string, forwardingRule string, targetreference *TargetReference) *GlobalForwardingRulesSetTargetCall {
	c := &GlobalForwardingRulesSetTargetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.forwardingRule = forwardingRule
	c.targetreference = targetreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *GlobalForwardingRulesSetTargetCall) RequestId(requestId string) *GlobalForwardingRulesSetTargetCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalForwardingRulesSetTargetCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesSetTargetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalForwardingRulesSetTargetCall) Context(ctx context.Context) *GlobalForwardingRulesSetTargetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalForwardingRulesSetTargetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalForwardingRulesSetTargetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules/{forwardingRule}/setTarget")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"forwardingRule": c.forwardingRule,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalForwardingRules.setTarget" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *GlobalForwardingRulesSetTargetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes target URL for the GlobalForwardingRule resource. The new target should be of the same type as the old target. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.globalForwardingRules.setTarget",
	//   "parameterOrder": [
	//     "project",
	//     "forwardingRule"
	//   ],
	//   "parameters": {
	//     "forwardingRule": {
	//       "description": "Name of the ForwardingRule resource in which target is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/forwardingRules/{forwardingRule}/setTarget",
	//   "request": {
	//     "$ref": "TargetReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.globalOperations.aggregatedList":

type GlobalOperationsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of all operations. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalOperations/aggregatedList
func (r *GlobalOperationsService) AggregatedList(project string) *GlobalOperationsAggregatedListCall {
	c := &GlobalOperationsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *GlobalOperationsAggregatedListCall) Filter(filter string) *GlobalOperationsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *GlobalOperationsAggregatedListCall) MaxResults(maxResults int64) *GlobalOperationsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *GlobalOperationsAggregatedListCall) OrderBy(orderBy string) *GlobalOperationsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *GlobalOperationsAggregatedListCall) PageToken(pageToken string) *GlobalOperationsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalOperationsAggregatedListCall) Fields(s ...googleapi.Field) *GlobalOperationsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GlobalOperationsAggregatedListCall) IfNoneMatch(entityTag string) *GlobalOperationsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalOperationsAggregatedListCall) Context(ctx context.Context) *GlobalOperationsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalOperationsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalOperationsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalOperations.aggregatedList" call.
// Exactly one of *OperationAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *OperationAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *GlobalOperationsAggregatedListCall) Do(opts ...googleapi.CallOption) (*OperationAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperationAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of all operations. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.globalOperations.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/operations",
	//   "response": {
	//     "$ref": "OperationAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *GlobalOperationsAggregatedListCall) Pages(ctx context.Context, f func(*OperationAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.globalOperations.delete":

type GlobalOperationsDeleteCall struct {
	s          *Service
	project    string
	operation  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified Operations resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalOperations/delete
func (r *GlobalOperationsService) Delete(project string, operation string) *GlobalOperationsDeleteCall {
	c := &GlobalOperationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.operation = operation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalOperationsDeleteCall) Fields(s ...googleapi.Field) *GlobalOperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalOperationsDeleteCall) Context(ctx context.Context) *GlobalOperationsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalOperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalOperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/operations/{operation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"operation": c.operation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalOperations.delete" call.
func (c *GlobalOperationsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes the specified Operations resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.globalOperations.delete",
	//   "parameterOrder": [
	//     "project",
	//     "operation"
	//   ],
	//   "parameters": {
	//     "operation": {
	//       "description": "Name of the Operations resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/operations/{operation}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.globalOperations.get":

type GlobalOperationsGetCall struct {
	s            *Service
	project      string
	operation    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified Operations resource. Gets a list of
// operations by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalOperations/get
func (r *GlobalOperationsService) Get(project string, operation string) *GlobalOperationsGetCall {
	c := &GlobalOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.operation = operation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalOperationsGetCall) Fields(s ...googleapi.Field) *GlobalOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GlobalOperationsGetCall) IfNoneMatch(entityTag string) *GlobalOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalOperationsGetCall) Context(ctx context.Context) *GlobalOperationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/operations/{operation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"operation": c.operation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalOperations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *GlobalOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the specified Operations resource. Gets a list of operations by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.globalOperations.get",
	//   "parameterOrder": [
	//     "project",
	//     "operation"
	//   ],
	//   "parameters": {
	//     "operation": {
	//       "description": "Name of the Operations resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/operations/{operation}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.globalOperations.list":

type GlobalOperationsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of Operation resources contained within the
// specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/globalOperations/list
func (r *GlobalOperationsService) List(project string) *GlobalOperationsListCall {
	c := &GlobalOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *GlobalOperationsListCall) Filter(filter string) *GlobalOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *GlobalOperationsListCall) MaxResults(maxResults int64) *GlobalOperationsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *GlobalOperationsListCall) OrderBy(orderBy string) *GlobalOperationsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *GlobalOperationsListCall) PageToken(pageToken string) *GlobalOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GlobalOperationsListCall) Fields(s ...googleapi.Field) *GlobalOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GlobalOperationsListCall) IfNoneMatch(entityTag string) *GlobalOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GlobalOperationsListCall) Context(ctx context.Context) *GlobalOperationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GlobalOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GlobalOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.globalOperations.list" call.
// Exactly one of *OperationList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *OperationList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *GlobalOperationsListCall) Do(opts ...googleapi.CallOption) (*OperationList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperationList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of Operation resources contained within the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.globalOperations.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/operations",
	//   "response": {
	//     "$ref": "OperationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *GlobalOperationsListCall) Pages(ctx context.Context, f func(*OperationList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.healthChecks.aggregatedList":

type HealthChecksAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of all HealthCheck resources,
// regional and global, available to the specified project. (==
// suppress_warning http-rest-shadowed ==)
func (r *HealthChecksService) AggregatedList(project string) *HealthChecksAggregatedListCall {
	c := &HealthChecksAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *HealthChecksAggregatedListCall) Filter(filter string) *HealthChecksAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *HealthChecksAggregatedListCall) MaxResults(maxResults int64) *HealthChecksAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *HealthChecksAggregatedListCall) OrderBy(orderBy string) *HealthChecksAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *HealthChecksAggregatedListCall) PageToken(pageToken string) *HealthChecksAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HealthChecksAggregatedListCall) Fields(s ...googleapi.Field) *HealthChecksAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *HealthChecksAggregatedListCall) IfNoneMatch(entityTag string) *HealthChecksAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HealthChecksAggregatedListCall) Context(ctx context.Context) *HealthChecksAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HealthChecksAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HealthChecksAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/healthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.healthChecks.aggregatedList" call.
// Exactly one of *HealthChecksAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *HealthChecksAggregatedList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *HealthChecksAggregatedListCall) Do(opts ...googleapi.CallOption) (*HealthChecksAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HealthChecksAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of all HealthCheck resources, regional and global, available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.healthChecks.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Name of the project scoping this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/healthChecks",
	//   "response": {
	//     "$ref": "HealthChecksAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *HealthChecksAggregatedListCall) Pages(ctx context.Context, f func(*HealthChecksAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.healthChecks.delete":

type HealthChecksDeleteCall struct {
	s           *Service
	project     string
	healthCheck string
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Delete: Deletes the specified HealthCheck resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *HealthChecksService) Delete(project string, healthCheck string) *HealthChecksDeleteCall {
	c := &HealthChecksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.healthCheck = healthCheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HealthChecksDeleteCall) RequestId(requestId string) *HealthChecksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HealthChecksDeleteCall) Fields(s ...googleapi.Field) *HealthChecksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HealthChecksDeleteCall) Context(ctx context.Context) *HealthChecksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HealthChecksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HealthChecksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.healthChecks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HealthChecksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified HealthCheck resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.healthChecks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/healthChecks/{healthCheck}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.healthChecks.get":

type HealthChecksGetCall struct {
	s            *Service
	project      string
	healthCheck  string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified HealthCheck resource. Gets a list of
// available health checks by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *HealthChecksService) Get(project string, healthCheck string) *HealthChecksGetCall {
	c := &HealthChecksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.healthCheck = healthCheck
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HealthChecksGetCall) Fields(s ...googleapi.Field) *HealthChecksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *HealthChecksGetCall) IfNoneMatch(entityTag string) *HealthChecksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HealthChecksGetCall) Context(ctx context.Context) *HealthChecksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HealthChecksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HealthChecksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.healthChecks.get" call.
// Exactly one of *HealthCheck or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *HealthCheck.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HealthChecksGetCall) Do(opts ...googleapi.CallOption) (*HealthCheck, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HealthCheck{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified HealthCheck resource. Gets a list of available health checks by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.healthChecks.get",
	//   "parameterOrder": [
	//     "project",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/healthChecks/{healthCheck}",
	//   "response": {
	//     "$ref": "HealthCheck"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.healthChecks.insert":

type HealthChecksInsertCall struct {
	s           *Service
	project     string
	healthcheck *HealthCheck
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Insert: Creates a HealthCheck resource in the specified project using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *HealthChecksService) Insert(project string, healthcheck *HealthCheck) *HealthChecksInsertCall {
	c := &HealthChecksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.healthcheck = healthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HealthChecksInsertCall) RequestId(requestId string) *HealthChecksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HealthChecksInsertCall) Fields(s ...googleapi.Field) *HealthChecksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HealthChecksInsertCall) Context(ctx context.Context) *HealthChecksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HealthChecksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HealthChecksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.healthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/healthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.healthChecks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HealthChecksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a HealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.healthChecks.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/healthChecks",
	//   "request": {
	//     "$ref": "HealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.healthChecks.list":

type HealthChecksListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of HealthCheck resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *HealthChecksService) List(project string) *HealthChecksListCall {
	c := &HealthChecksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *HealthChecksListCall) Filter(filter string) *HealthChecksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *HealthChecksListCall) MaxResults(maxResults int64) *HealthChecksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *HealthChecksListCall) OrderBy(orderBy string) *HealthChecksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *HealthChecksListCall) PageToken(pageToken string) *HealthChecksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HealthChecksListCall) Fields(s ...googleapi.Field) *HealthChecksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *HealthChecksListCall) IfNoneMatch(entityTag string) *HealthChecksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HealthChecksListCall) Context(ctx context.Context) *HealthChecksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HealthChecksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HealthChecksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/healthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.healthChecks.list" call.
// Exactly one of *HealthCheckList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *HealthCheckList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *HealthChecksListCall) Do(opts ...googleapi.CallOption) (*HealthCheckList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HealthCheckList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of HealthCheck resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.healthChecks.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/healthChecks",
	//   "response": {
	//     "$ref": "HealthCheckList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *HealthChecksListCall) Pages(ctx context.Context, f func(*HealthCheckList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.healthChecks.patch":

type HealthChecksPatchCall struct {
	s           *Service
	project     string
	healthCheck string
	healthcheck *HealthCheck
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Patch: Updates a HealthCheck resource in the specified project using
// the data included in the request. This method supports PATCH
// semantics and uses the JSON merge patch format and processing rules.
// (== suppress_warning http-rest-shadowed ==)
func (r *HealthChecksService) Patch(project string, healthCheck string, healthcheck *HealthCheck) *HealthChecksPatchCall {
	c := &HealthChecksPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.healthCheck = healthCheck
	c.healthcheck = healthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HealthChecksPatchCall) RequestId(requestId string) *HealthChecksPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HealthChecksPatchCall) Fields(s ...googleapi.Field) *HealthChecksPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HealthChecksPatchCall) Context(ctx context.Context) *HealthChecksPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HealthChecksPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HealthChecksPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.healthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.healthChecks.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HealthChecksPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.healthChecks.patch",
	//   "parameterOrder": [
	//     "project",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/healthChecks/{healthCheck}",
	//   "request": {
	//     "$ref": "HealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.healthChecks.update":

type HealthChecksUpdateCall struct {
	s           *Service
	project     string
	healthCheck string
	healthcheck *HealthCheck
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Update: Updates a HealthCheck resource in the specified project using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *HealthChecksService) Update(project string, healthCheck string, healthcheck *HealthCheck) *HealthChecksUpdateCall {
	c := &HealthChecksUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.healthCheck = healthCheck
	c.healthcheck = healthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HealthChecksUpdateCall) RequestId(requestId string) *HealthChecksUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HealthChecksUpdateCall) Fields(s ...googleapi.Field) *HealthChecksUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HealthChecksUpdateCall) Context(ctx context.Context) *HealthChecksUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HealthChecksUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HealthChecksUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.healthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.healthChecks.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HealthChecksUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.healthChecks.update",
	//   "parameterOrder": [
	//     "project",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/healthChecks/{healthCheck}",
	//   "request": {
	//     "$ref": "HealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpHealthChecks.delete":

type HttpHealthChecksDeleteCall struct {
	s               *Service
	project         string
	httpHealthCheck string
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Delete: Deletes the specified HttpHealthCheck resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/httpHealthChecks/delete
func (r *HttpHealthChecksService) Delete(project string, httpHealthCheck string) *HttpHealthChecksDeleteCall {
	c := &HttpHealthChecksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpHealthCheck = httpHealthCheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpHealthChecksDeleteCall) RequestId(requestId string) *HttpHealthChecksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpHealthChecksDeleteCall) Fields(s ...googleapi.Field) *HttpHealthChecksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpHealthChecksDeleteCall) Context(ctx context.Context) *HttpHealthChecksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpHealthChecksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpHealthChecksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"httpHealthCheck": c.httpHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpHealthChecks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpHealthChecksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified HttpHealthCheck resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.httpHealthChecks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "httpHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpHealthCheck": {
	//       "description": "Name of the HttpHealthCheck resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpHealthChecks/{httpHealthCheck}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpHealthChecks.get":

type HttpHealthChecksGetCall struct {
	s               *Service
	project         string
	httpHealthCheck string
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
	header_         http.Header
}

// Get: Returns the specified HttpHealthCheck resource. Gets a list of
// available HTTP health checks by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/httpHealthChecks/get
func (r *HttpHealthChecksService) Get(project string, httpHealthCheck string) *HttpHealthChecksGetCall {
	c := &HttpHealthChecksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpHealthCheck = httpHealthCheck
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpHealthChecksGetCall) Fields(s ...googleapi.Field) *HttpHealthChecksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *HttpHealthChecksGetCall) IfNoneMatch(entityTag string) *HttpHealthChecksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpHealthChecksGetCall) Context(ctx context.Context) *HttpHealthChecksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpHealthChecksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpHealthChecksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"httpHealthCheck": c.httpHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpHealthChecks.get" call.
// Exactly one of *HttpHealthCheck or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *HttpHealthCheck.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *HttpHealthChecksGetCall) Do(opts ...googleapi.CallOption) (*HttpHealthCheck, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HttpHealthCheck{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified HttpHealthCheck resource. Gets a list of available HTTP health checks by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.httpHealthChecks.get",
	//   "parameterOrder": [
	//     "project",
	//     "httpHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpHealthCheck": {
	//       "description": "Name of the HttpHealthCheck resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpHealthChecks/{httpHealthCheck}",
	//   "response": {
	//     "$ref": "HttpHealthCheck"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.httpHealthChecks.insert":

type HttpHealthChecksInsertCall struct {
	s               *Service
	project         string
	httphealthcheck *HttpHealthCheck
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Creates a HttpHealthCheck resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/httpHealthChecks/insert
func (r *HttpHealthChecksService) Insert(project string, httphealthcheck *HttpHealthCheck) *HttpHealthChecksInsertCall {
	c := &HttpHealthChecksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httphealthcheck = httphealthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpHealthChecksInsertCall) RequestId(requestId string) *HttpHealthChecksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpHealthChecksInsertCall) Fields(s ...googleapi.Field) *HttpHealthChecksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpHealthChecksInsertCall) Context(ctx context.Context) *HttpHealthChecksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpHealthChecksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpHealthChecksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.httphealthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpHealthChecks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpHealthChecksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a HttpHealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.httpHealthChecks.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpHealthChecks",
	//   "request": {
	//     "$ref": "HttpHealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpHealthChecks.list":

type HttpHealthChecksListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of HttpHealthCheck resources available to
// the specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/httpHealthChecks/list
func (r *HttpHealthChecksService) List(project string) *HttpHealthChecksListCall {
	c := &HttpHealthChecksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *HttpHealthChecksListCall) Filter(filter string) *HttpHealthChecksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *HttpHealthChecksListCall) MaxResults(maxResults int64) *HttpHealthChecksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *HttpHealthChecksListCall) OrderBy(orderBy string) *HttpHealthChecksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *HttpHealthChecksListCall) PageToken(pageToken string) *HttpHealthChecksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpHealthChecksListCall) Fields(s ...googleapi.Field) *HttpHealthChecksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *HttpHealthChecksListCall) IfNoneMatch(entityTag string) *HttpHealthChecksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpHealthChecksListCall) Context(ctx context.Context) *HttpHealthChecksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpHealthChecksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpHealthChecksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpHealthChecks.list" call.
// Exactly one of *HttpHealthCheckList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *HttpHealthCheckList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *HttpHealthChecksListCall) Do(opts ...googleapi.CallOption) (*HttpHealthCheckList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HttpHealthCheckList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of HttpHealthCheck resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.httpHealthChecks.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpHealthChecks",
	//   "response": {
	//     "$ref": "HttpHealthCheckList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *HttpHealthChecksListCall) Pages(ctx context.Context, f func(*HttpHealthCheckList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.httpHealthChecks.patch":

type HttpHealthChecksPatchCall struct {
	s               *Service
	project         string
	httpHealthCheck string
	httphealthcheck *HttpHealthCheck
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Patch: Updates a HttpHealthCheck resource in the specified project
// using the data included in the request. This method supports PATCH
// semantics and uses the JSON merge patch format and processing rules.
// (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/httpHealthChecks/patch
func (r *HttpHealthChecksService) Patch(project string, httpHealthCheck string, httphealthcheck *HttpHealthCheck) *HttpHealthChecksPatchCall {
	c := &HttpHealthChecksPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpHealthCheck = httpHealthCheck
	c.httphealthcheck = httphealthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpHealthChecksPatchCall) RequestId(requestId string) *HttpHealthChecksPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpHealthChecksPatchCall) Fields(s ...googleapi.Field) *HttpHealthChecksPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpHealthChecksPatchCall) Context(ctx context.Context) *HttpHealthChecksPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpHealthChecksPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpHealthChecksPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.httphealthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"httpHealthCheck": c.httpHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpHealthChecks.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpHealthChecksPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HttpHealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.httpHealthChecks.patch",
	//   "parameterOrder": [
	//     "project",
	//     "httpHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpHealthCheck": {
	//       "description": "Name of the HttpHealthCheck resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpHealthChecks/{httpHealthCheck}",
	//   "request": {
	//     "$ref": "HttpHealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpHealthChecks.update":

type HttpHealthChecksUpdateCall struct {
	s               *Service
	project         string
	httpHealthCheck string
	httphealthcheck *HttpHealthCheck
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Update: Updates a HttpHealthCheck resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/httpHealthChecks/update
func (r *HttpHealthChecksService) Update(project string, httpHealthCheck string, httphealthcheck *HttpHealthCheck) *HttpHealthChecksUpdateCall {
	c := &HttpHealthChecksUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpHealthCheck = httpHealthCheck
	c.httphealthcheck = httphealthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpHealthChecksUpdateCall) RequestId(requestId string) *HttpHealthChecksUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpHealthChecksUpdateCall) Fields(s ...googleapi.Field) *HttpHealthChecksUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpHealthChecksUpdateCall) Context(ctx context.Context) *HttpHealthChecksUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpHealthChecksUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpHealthChecksUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.httphealthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"httpHealthCheck": c.httpHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpHealthChecks.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpHealthChecksUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HttpHealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.httpHealthChecks.update",
	//   "parameterOrder": [
	//     "project",
	//     "httpHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpHealthCheck": {
	//       "description": "Name of the HttpHealthCheck resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpHealthChecks/{httpHealthCheck}",
	//   "request": {
	//     "$ref": "HttpHealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpsHealthChecks.delete":

type HttpsHealthChecksDeleteCall struct {
	s                *Service
	project          string
	httpsHealthCheck string
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Delete: Deletes the specified HttpsHealthCheck resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *HttpsHealthChecksService) Delete(project string, httpsHealthCheck string) *HttpsHealthChecksDeleteCall {
	c := &HttpsHealthChecksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpsHealthCheck = httpsHealthCheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpsHealthChecksDeleteCall) RequestId(requestId string) *HttpsHealthChecksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpsHealthChecksDeleteCall) Fields(s ...googleapi.Field) *HttpsHealthChecksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpsHealthChecksDeleteCall) Context(ctx context.Context) *HttpsHealthChecksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpsHealthChecksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpsHealthChecksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpsHealthChecks/{httpsHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"httpsHealthCheck": c.httpsHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpsHealthChecks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpsHealthChecksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified HttpsHealthCheck resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.httpsHealthChecks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "httpsHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpsHealthCheck": {
	//       "description": "Name of the HttpsHealthCheck resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpsHealthChecks/{httpsHealthCheck}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpsHealthChecks.get":

type HttpsHealthChecksGetCall struct {
	s                *Service
	project          string
	httpsHealthCheck string
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// Get: Returns the specified HttpsHealthCheck resource. Gets a list of
// available HTTPS health checks by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *HttpsHealthChecksService) Get(project string, httpsHealthCheck string) *HttpsHealthChecksGetCall {
	c := &HttpsHealthChecksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpsHealthCheck = httpsHealthCheck
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpsHealthChecksGetCall) Fields(s ...googleapi.Field) *HttpsHealthChecksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *HttpsHealthChecksGetCall) IfNoneMatch(entityTag string) *HttpsHealthChecksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpsHealthChecksGetCall) Context(ctx context.Context) *HttpsHealthChecksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpsHealthChecksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpsHealthChecksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpsHealthChecks/{httpsHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"httpsHealthCheck": c.httpsHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpsHealthChecks.get" call.
// Exactly one of *HttpsHealthCheck or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *HttpsHealthCheck.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *HttpsHealthChecksGetCall) Do(opts ...googleapi.CallOption) (*HttpsHealthCheck, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HttpsHealthCheck{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified HttpsHealthCheck resource. Gets a list of available HTTPS health checks by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.httpsHealthChecks.get",
	//   "parameterOrder": [
	//     "project",
	//     "httpsHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpsHealthCheck": {
	//       "description": "Name of the HttpsHealthCheck resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpsHealthChecks/{httpsHealthCheck}",
	//   "response": {
	//     "$ref": "HttpsHealthCheck"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.httpsHealthChecks.insert":

type HttpsHealthChecksInsertCall struct {
	s                *Service
	project          string
	httpshealthcheck *HttpsHealthCheck
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Insert: Creates a HttpsHealthCheck resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *HttpsHealthChecksService) Insert(project string, httpshealthcheck *HttpsHealthCheck) *HttpsHealthChecksInsertCall {
	c := &HttpsHealthChecksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpshealthcheck = httpshealthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpsHealthChecksInsertCall) RequestId(requestId string) *HttpsHealthChecksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpsHealthChecksInsertCall) Fields(s ...googleapi.Field) *HttpsHealthChecksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpsHealthChecksInsertCall) Context(ctx context.Context) *HttpsHealthChecksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpsHealthChecksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpsHealthChecksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.httpshealthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpsHealthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpsHealthChecks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpsHealthChecksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a HttpsHealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.httpsHealthChecks.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpsHealthChecks",
	//   "request": {
	//     "$ref": "HttpsHealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpsHealthChecks.list":

type HttpsHealthChecksListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of HttpsHealthCheck resources available to
// the specified project. (== suppress_warning http-rest-shadowed ==)
func (r *HttpsHealthChecksService) List(project string) *HttpsHealthChecksListCall {
	c := &HttpsHealthChecksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *HttpsHealthChecksListCall) Filter(filter string) *HttpsHealthChecksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *HttpsHealthChecksListCall) MaxResults(maxResults int64) *HttpsHealthChecksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *HttpsHealthChecksListCall) OrderBy(orderBy string) *HttpsHealthChecksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *HttpsHealthChecksListCall) PageToken(pageToken string) *HttpsHealthChecksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpsHealthChecksListCall) Fields(s ...googleapi.Field) *HttpsHealthChecksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *HttpsHealthChecksListCall) IfNoneMatch(entityTag string) *HttpsHealthChecksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpsHealthChecksListCall) Context(ctx context.Context) *HttpsHealthChecksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpsHealthChecksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpsHealthChecksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpsHealthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpsHealthChecks.list" call.
// Exactly one of *HttpsHealthCheckList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *HttpsHealthCheckList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *HttpsHealthChecksListCall) Do(opts ...googleapi.CallOption) (*HttpsHealthCheckList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HttpsHealthCheckList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of HttpsHealthCheck resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.httpsHealthChecks.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpsHealthChecks",
	//   "response": {
	//     "$ref": "HttpsHealthCheckList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *HttpsHealthChecksListCall) Pages(ctx context.Context, f func(*HttpsHealthCheckList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.httpsHealthChecks.patch":

type HttpsHealthChecksPatchCall struct {
	s                *Service
	project          string
	httpsHealthCheck string
	httpshealthcheck *HttpsHealthCheck
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Patch: Updates a HttpsHealthCheck resource in the specified project
// using the data included in the request. This method supports PATCH
// semantics and uses the JSON merge patch format and processing rules.
// (== suppress_warning http-rest-shadowed ==)
func (r *HttpsHealthChecksService) Patch(project string, httpsHealthCheck string, httpshealthcheck *HttpsHealthCheck) *HttpsHealthChecksPatchCall {
	c := &HttpsHealthChecksPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpsHealthCheck = httpsHealthCheck
	c.httpshealthcheck = httpshealthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpsHealthChecksPatchCall) RequestId(requestId string) *HttpsHealthChecksPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpsHealthChecksPatchCall) Fields(s ...googleapi.Field) *HttpsHealthChecksPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpsHealthChecksPatchCall) Context(ctx context.Context) *HttpsHealthChecksPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpsHealthChecksPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpsHealthChecksPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.httpshealthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpsHealthChecks/{httpsHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"httpsHealthCheck": c.httpsHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpsHealthChecks.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpsHealthChecksPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HttpsHealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.httpsHealthChecks.patch",
	//   "parameterOrder": [
	//     "project",
	//     "httpsHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpsHealthCheck": {
	//       "description": "Name of the HttpsHealthCheck resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpsHealthChecks/{httpsHealthCheck}",
	//   "request": {
	//     "$ref": "HttpsHealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.httpsHealthChecks.update":

type HttpsHealthChecksUpdateCall struct {
	s                *Service
	project          string
	httpsHealthCheck string
	httpshealthcheck *HttpsHealthCheck
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Update: Updates a HttpsHealthCheck resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *HttpsHealthChecksService) Update(project string, httpsHealthCheck string, httpshealthcheck *HttpsHealthCheck) *HttpsHealthChecksUpdateCall {
	c := &HttpsHealthChecksUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.httpsHealthCheck = httpsHealthCheck
	c.httpshealthcheck = httpshealthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *HttpsHealthChecksUpdateCall) RequestId(requestId string) *HttpsHealthChecksUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *HttpsHealthChecksUpdateCall) Fields(s ...googleapi.Field) *HttpsHealthChecksUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *HttpsHealthChecksUpdateCall) Context(ctx context.Context) *HttpsHealthChecksUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *HttpsHealthChecksUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HttpsHealthChecksUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.httpshealthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpsHealthChecks/{httpsHealthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"httpsHealthCheck": c.httpsHealthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.httpsHealthChecks.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *HttpsHealthChecksUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HttpsHealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.httpsHealthChecks.update",
	//   "parameterOrder": [
	//     "project",
	//     "httpsHealthCheck"
	//   ],
	//   "parameters": {
	//     "httpsHealthCheck": {
	//       "description": "Name of the HttpsHealthCheck resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/httpsHealthChecks/{httpsHealthCheck}",
	//   "request": {
	//     "$ref": "HttpsHealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.images.delete":

type ImagesDeleteCall struct {
	s          *Service
	project    string
	image      string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified image. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/images/delete
func (r *ImagesService) Delete(project string, image string) *ImagesDeleteCall {
	c := &ImagesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.image = image
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ImagesDeleteCall) RequestId(requestId string) *ImagesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesDeleteCall) Fields(s ...googleapi.Field) *ImagesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesDeleteCall) Context(ctx context.Context) *ImagesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{image}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"image":   c.image,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ImagesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified image. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.images.delete",
	//   "parameterOrder": [
	//     "project",
	//     "image"
	//   ],
	//   "parameters": {
	//     "image": {
	//       "description": "Name of the image resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/{image}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.images.deprecate":

type ImagesDeprecateCall struct {
	s                 *Service
	project           string
	image             string
	deprecationstatus *DeprecationStatus
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Deprecate: Sets the deprecation status of an image.
//
// If an empty request body is given, clears the deprecation status
// instead. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/images/deprecate
func (r *ImagesService) Deprecate(project string, image string, deprecationstatus *DeprecationStatus) *ImagesDeprecateCall {
	c := &ImagesDeprecateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.image = image
	c.deprecationstatus = deprecationstatus
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ImagesDeprecateCall) RequestId(requestId string) *ImagesDeprecateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesDeprecateCall) Fields(s ...googleapi.Field) *ImagesDeprecateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesDeprecateCall) Context(ctx context.Context) *ImagesDeprecateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesDeprecateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesDeprecateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.deprecationstatus)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{image}/deprecate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"image":   c.image,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.deprecate" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ImagesDeprecateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the deprecation status of an image.\n\nIf an empty request body is given, clears the deprecation status instead. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.images.deprecate",
	//   "parameterOrder": [
	//     "project",
	//     "image"
	//   ],
	//   "parameters": {
	//     "image": {
	//       "description": "Image name.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/{image}/deprecate",
	//   "request": {
	//     "$ref": "DeprecationStatus"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.images.get":

type ImagesGetCall struct {
	s            *Service
	project      string
	image        string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified image. Gets a list of available images by
// making a list() request. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/images/get
func (r *ImagesService) Get(project string, image string) *ImagesGetCall {
	c := &ImagesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.image = image
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesGetCall) Fields(s ...googleapi.Field) *ImagesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ImagesGetCall) IfNoneMatch(entityTag string) *ImagesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesGetCall) Context(ctx context.Context) *ImagesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{image}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"image":   c.image,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.get" call.
// Exactly one of *Image or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Image.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ImagesGetCall) Do(opts ...googleapi.CallOption) (*Image, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Image{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified image. Gets a list of available images by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.images.get",
	//   "parameterOrder": [
	//     "project",
	//     "image"
	//   ],
	//   "parameters": {
	//     "image": {
	//       "description": "Name of the image resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/{image}",
	//   "response": {
	//     "$ref": "Image"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.images.getFromFamily":

type ImagesGetFromFamilyCall struct {
	s            *Service
	project      string
	family       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetFromFamily: Returns the latest image that is part of an image
// family and is not deprecated. (== suppress_warning http-rest-shadowed
// ==)
func (r *ImagesService) GetFromFamily(project string, family string) *ImagesGetFromFamilyCall {
	c := &ImagesGetFromFamilyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.family = family
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesGetFromFamilyCall) Fields(s ...googleapi.Field) *ImagesGetFromFamilyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ImagesGetFromFamilyCall) IfNoneMatch(entityTag string) *ImagesGetFromFamilyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesGetFromFamilyCall) Context(ctx context.Context) *ImagesGetFromFamilyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesGetFromFamilyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesGetFromFamilyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/family/{family}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"family":  c.family,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.getFromFamily" call.
// Exactly one of *Image or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Image.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ImagesGetFromFamilyCall) Do(opts ...googleapi.CallOption) (*Image, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Image{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the latest image that is part of an image family and is not deprecated. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.images.getFromFamily",
	//   "parameterOrder": [
	//     "project",
	//     "family"
	//   ],
	//   "parameters": {
	//     "family": {
	//       "description": "Name of the image family to search for.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/family/{family}",
	//   "response": {
	//     "$ref": "Image"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.images.getIamPolicy":

type ImagesGetIamPolicyCall struct {
	s            *Service
	project      string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *ImagesService) GetIamPolicy(project string, resource string) *ImagesGetIamPolicyCall {
	c := &ImagesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesGetIamPolicyCall) Fields(s ...googleapi.Field) *ImagesGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ImagesGetIamPolicyCall) IfNoneMatch(entityTag string) *ImagesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesGetIamPolicyCall) Context(ctx context.Context) *ImagesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ImagesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.images.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.images.insert":

type ImagesInsertCall struct {
	s          *Service
	project    string
	image      *Image
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates an image in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/images/insert
func (r *ImagesService) Insert(project string, image *Image) *ImagesInsertCall {
	c := &ImagesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.image = image
	return c
}

// ForceCreate sets the optional parameter "forceCreate": Force image
// creation if true.
func (c *ImagesInsertCall) ForceCreate(forceCreate bool) *ImagesInsertCall {
	c.urlParams_.Set("forceCreate", fmt.Sprint(forceCreate))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ImagesInsertCall) RequestId(requestId string) *ImagesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesInsertCall) Fields(s ...googleapi.Field) *ImagesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesInsertCall) Context(ctx context.Context) *ImagesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.image)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ImagesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an image in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.images.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "forceCreate": {
	//       "description": "Force image creation if true.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images",
	//   "request": {
	//     "$ref": "Image"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/devstorage.full_control",
	//     "https://www.googleapis.com/auth/devstorage.read_only",
	//     "https://www.googleapis.com/auth/devstorage.read_write"
	//   ]
	// }

}

// method id "compute.images.list":

type ImagesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of custom images available to the specified
// project. Custom images are images you create that belong to your
// project. This method does not get any images that belong to other
// projects, including publicly-available images, like Debian 8. If you
// want to get a list of publicly-available images, use this method to
// make a request to the respective image project, such as debian-cloud
// or windows-cloud. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/images/list
func (r *ImagesService) List(project string) *ImagesListCall {
	c := &ImagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ImagesListCall) Filter(filter string) *ImagesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ImagesListCall) MaxResults(maxResults int64) *ImagesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ImagesListCall) OrderBy(orderBy string) *ImagesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ImagesListCall) PageToken(pageToken string) *ImagesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesListCall) Fields(s ...googleapi.Field) *ImagesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ImagesListCall) IfNoneMatch(entityTag string) *ImagesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesListCall) Context(ctx context.Context) *ImagesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.list" call.
// Exactly one of *ImageList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ImageList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ImagesListCall) Do(opts ...googleapi.CallOption) (*ImageList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ImageList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of custom images available to the specified project. Custom images are images you create that belong to your project. This method does not get any images that belong to other projects, including publicly-available images, like Debian 8. If you want to get a list of publicly-available images, use this method to make a request to the respective image project, such as debian-cloud or windows-cloud. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.images.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images",
	//   "response": {
	//     "$ref": "ImageList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ImagesListCall) Pages(ctx context.Context, f func(*ImageList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.images.setIamPolicy":

type ImagesSetIamPolicyCall struct {
	s                      *Service
	project                string
	resource               string
	globalsetpolicyrequest *GlobalSetPolicyRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *ImagesService) SetIamPolicy(project string, resource string, globalsetpolicyrequest *GlobalSetPolicyRequest) *ImagesSetIamPolicyCall {
	c := &ImagesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.globalsetpolicyrequest = globalsetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesSetIamPolicyCall) Fields(s ...googleapi.Field) *ImagesSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesSetIamPolicyCall) Context(ctx context.Context) *ImagesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.globalsetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ImagesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.images.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "GlobalSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.images.setLabels":

type ImagesSetLabelsCall struct {
	s                      *Service
	project                string
	resource               string
	globalsetlabelsrequest *GlobalSetLabelsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetLabels: Sets the labels on an image. To learn more about labels,
// read the Labeling Resources documentation. (== suppress_warning
// http-rest-shadowed ==)
func (r *ImagesService) SetLabels(project string, resource string, globalsetlabelsrequest *GlobalSetLabelsRequest) *ImagesSetLabelsCall {
	c := &ImagesSetLabelsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.globalsetlabelsrequest = globalsetlabelsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesSetLabelsCall) Fields(s ...googleapi.Field) *ImagesSetLabelsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesSetLabelsCall) Context(ctx context.Context) *ImagesSetLabelsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesSetLabelsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesSetLabelsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.globalsetlabelsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{resource}/setLabels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.setLabels" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ImagesSetLabelsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the labels on an image. To learn more about labels, read the Labeling Resources documentation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.images.setLabels",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/{resource}/setLabels",
	//   "request": {
	//     "$ref": "GlobalSetLabelsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.images.testIamPermissions":

type ImagesTestIamPermissionsCall struct {
	s                      *Service
	project                string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *ImagesService) TestIamPermissions(project string, resource string, testpermissionsrequest *TestPermissionsRequest) *ImagesTestIamPermissionsCall {
	c := &ImagesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ImagesTestIamPermissionsCall) Fields(s ...googleapi.Field) *ImagesTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ImagesTestIamPermissionsCall) Context(ctx context.Context) *ImagesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ImagesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ImagesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.images.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ImagesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.images.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/images/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.abandonInstances":

type InstanceGroupManagersAbandonInstancesCall struct {
	s                                            *Service
	project                                      string
	zone                                         string
	instanceGroupManager                         string
	instancegroupmanagersabandoninstancesrequest *InstanceGroupManagersAbandonInstancesRequest
	urlParams_                                   gensupport.URLParams
	ctx_                                         context.Context
	header_                                      http.Header
}

// AbandonInstances: Flags the specified instances to be removed from
// the managed instance group. Abandoning an instance does not delete
// the instance, but it does remove the instance from any target pools
// that are applied by the managed instance group. This method reduces
// the targetSize of the managed instance group by the number of
// instances that you abandon. This operation is marked as DONE when the
// action is scheduled even if the instances have not yet been removed
// from the group. You must separately verify the status of the
// abandoning action with the listmanagedinstances method.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or
// deleted.
//
// You can specify a maximum of 1000 instances with this method per
// request. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) AbandonInstances(project string, zone string, instanceGroupManager string, instancegroupmanagersabandoninstancesrequest *InstanceGroupManagersAbandonInstancesRequest) *InstanceGroupManagersAbandonInstancesCall {
	c := &InstanceGroupManagersAbandonInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	c.instancegroupmanagersabandoninstancesrequest = instancegroupmanagersabandoninstancesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersAbandonInstancesCall) RequestId(requestId string) *InstanceGroupManagersAbandonInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersAbandonInstancesCall) Fields(s ...googleapi.Field) *InstanceGroupManagersAbandonInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersAbandonInstancesCall) Context(ctx context.Context) *InstanceGroupManagersAbandonInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersAbandonInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersAbandonInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanagersabandoninstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/abandonInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.abandonInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersAbandonInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Flags the specified instances to be removed from the managed instance group. Abandoning an instance does not delete the instance, but it does remove the instance from any target pools that are applied by the managed instance group. This method reduces the targetSize of the managed instance group by the number of instances that you abandon. This operation is marked as DONE when the action is scheduled even if the instances have not yet been removed from the group. You must separately verify the status of the abandoning action with the listmanagedinstances method.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.\n\nYou can specify a maximum of 1000 instances with this method per request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.abandonInstances",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/abandonInstances",
	//   "request": {
	//     "$ref": "InstanceGroupManagersAbandonInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.aggregatedList":

type InstanceGroupManagersAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of managed instance groups and
// groups them by zone. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) AggregatedList(project string) *InstanceGroupManagersAggregatedListCall {
	c := &InstanceGroupManagersAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstanceGroupManagersAggregatedListCall) Filter(filter string) *InstanceGroupManagersAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstanceGroupManagersAggregatedListCall) MaxResults(maxResults int64) *InstanceGroupManagersAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstanceGroupManagersAggregatedListCall) OrderBy(orderBy string) *InstanceGroupManagersAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstanceGroupManagersAggregatedListCall) PageToken(pageToken string) *InstanceGroupManagersAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersAggregatedListCall) Fields(s ...googleapi.Field) *InstanceGroupManagersAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceGroupManagersAggregatedListCall) IfNoneMatch(entityTag string) *InstanceGroupManagersAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersAggregatedListCall) Context(ctx context.Context) *InstanceGroupManagersAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/instanceGroupManagers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.aggregatedList" call.
// Exactly one of *InstanceGroupManagerAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *InstanceGroupManagerAggregatedList.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *InstanceGroupManagersAggregatedListCall) Do(opts ...googleapi.CallOption) (*InstanceGroupManagerAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupManagerAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of managed instance groups and groups them by zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceGroupManagers.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/instanceGroupManagers",
	//   "response": {
	//     "$ref": "InstanceGroupManagerAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstanceGroupManagersAggregatedListCall) Pages(ctx context.Context, f func(*InstanceGroupManagerAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instanceGroupManagers.delete":

type InstanceGroupManagersDeleteCall struct {
	s                    *Service
	project              string
	zone                 string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Delete: Deletes the specified managed instance group and all of the
// instances in that group. Note that the instance group must not belong
// to a backend service. Read  Deleting an instance group for more
// information. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) Delete(project string, zone string, instanceGroupManager string) *InstanceGroupManagersDeleteCall {
	c := &InstanceGroupManagersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersDeleteCall) RequestId(requestId string) *InstanceGroupManagersDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersDeleteCall) Fields(s ...googleapi.Field) *InstanceGroupManagersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersDeleteCall) Context(ctx context.Context) *InstanceGroupManagersDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified managed instance group and all of the instances in that group. Note that the instance group must not belong to a backend service. Read  Deleting an instance group for more information. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.instanceGroupManagers.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group to delete.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.deleteInstances":

type InstanceGroupManagersDeleteInstancesCall struct {
	s                                           *Service
	project                                     string
	zone                                        string
	instanceGroupManager                        string
	instancegroupmanagersdeleteinstancesrequest *InstanceGroupManagersDeleteInstancesRequest
	urlParams_                                  gensupport.URLParams
	ctx_                                        context.Context
	header_                                     http.Header
}

// DeleteInstances: Flags the specified instances in the managed
// instance group for immediate deletion. The instances are also removed
// from any target pools of which they were a member. This method
// reduces the targetSize of the managed instance group by the number of
// instances that you delete. This operation is marked as DONE when the
// action is scheduled even if the instances are still being deleted.
// You must separately verify the status of the deleting action with the
// listmanagedinstances method.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or
// deleted.
//
// You can specify a maximum of 1000 instances with this method per
// request. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) DeleteInstances(project string, zone string, instanceGroupManager string, instancegroupmanagersdeleteinstancesrequest *InstanceGroupManagersDeleteInstancesRequest) *InstanceGroupManagersDeleteInstancesCall {
	c := &InstanceGroupManagersDeleteInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	c.instancegroupmanagersdeleteinstancesrequest = instancegroupmanagersdeleteinstancesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersDeleteInstancesCall) RequestId(requestId string) *InstanceGroupManagersDeleteInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersDeleteInstancesCall) Fields(s ...googleapi.Field) *InstanceGroupManagersDeleteInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersDeleteInstancesCall) Context(ctx context.Context) *InstanceGroupManagersDeleteInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersDeleteInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersDeleteInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanagersdeleteinstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/deleteInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.deleteInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersDeleteInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Flags the specified instances in the managed instance group for immediate deletion. The instances are also removed from any target pools of which they were a member. This method reduces the targetSize of the managed instance group by the number of instances that you delete. This operation is marked as DONE when the action is scheduled even if the instances are still being deleted. You must separately verify the status of the deleting action with the listmanagedinstances method.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.\n\nYou can specify a maximum of 1000 instances with this method per request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.deleteInstances",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/deleteInstances",
	//   "request": {
	//     "$ref": "InstanceGroupManagersDeleteInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.get":

type InstanceGroupManagersGetCall struct {
	s                    *Service
	project              string
	zone                 string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ifNoneMatch_         string
	ctx_                 context.Context
	header_              http.Header
}

// Get: Returns all of the details about the specified managed instance
// group. Gets a list of available managed instance groups by making a
// list() request. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) Get(project string, zone string, instanceGroupManager string) *InstanceGroupManagersGetCall {
	c := &InstanceGroupManagersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersGetCall) Fields(s ...googleapi.Field) *InstanceGroupManagersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceGroupManagersGetCall) IfNoneMatch(entityTag string) *InstanceGroupManagersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersGetCall) Context(ctx context.Context) *InstanceGroupManagersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.get" call.
// Exactly one of *InstanceGroupManager or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InstanceGroupManager.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceGroupManagersGetCall) Do(opts ...googleapi.CallOption) (*InstanceGroupManager, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupManager{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns all of the details about the specified managed instance group. Gets a list of available managed instance groups by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceGroupManagers.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}",
	//   "response": {
	//     "$ref": "InstanceGroupManager"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.insert":

type InstanceGroupManagersInsertCall struct {
	s                    *Service
	project              string
	zone                 string
	instancegroupmanager *InstanceGroupManager
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Insert: Creates a managed instance group using the information that
// you specify in the request. After the group is created, instances in
// the group are created using the specified instance template. This
// operation is marked as DONE when the group is created even if the
// instances in the group have not yet been created. You must separately
// verify the status of the individual instances with the
// listmanagedinstances method.
//
// A managed instance group can have up to 1000 VM instances per group.
// Please contact Cloud Support if you need an increase in this limit.
// (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) Insert(project string, zone string, instancegroupmanager *InstanceGroupManager) *InstanceGroupManagersInsertCall {
	c := &InstanceGroupManagersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instancegroupmanager = instancegroupmanager
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersInsertCall) RequestId(requestId string) *InstanceGroupManagersInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersInsertCall) Fields(s ...googleapi.Field) *InstanceGroupManagersInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersInsertCall) Context(ctx context.Context) *InstanceGroupManagersInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanager)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a managed instance group using the information that you specify in the request. After the group is created, instances in the group are created using the specified instance template. This operation is marked as DONE when the group is created even if the instances in the group have not yet been created. You must separately verify the status of the individual instances with the listmanagedinstances method.\n\nA managed instance group can have up to 1000 VM instances per group. Please contact Cloud Support if you need an increase in this limit. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where you want to create the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers",
	//   "request": {
	//     "$ref": "InstanceGroupManager"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.list":

type InstanceGroupManagersListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of managed instance groups that are contained
// within the specified project and zone. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstanceGroupManagersService) List(project string, zone string) *InstanceGroupManagersListCall {
	c := &InstanceGroupManagersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstanceGroupManagersListCall) Filter(filter string) *InstanceGroupManagersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstanceGroupManagersListCall) MaxResults(maxResults int64) *InstanceGroupManagersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstanceGroupManagersListCall) OrderBy(orderBy string) *InstanceGroupManagersListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstanceGroupManagersListCall) PageToken(pageToken string) *InstanceGroupManagersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersListCall) Fields(s ...googleapi.Field) *InstanceGroupManagersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceGroupManagersListCall) IfNoneMatch(entityTag string) *InstanceGroupManagersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersListCall) Context(ctx context.Context) *InstanceGroupManagersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.list" call.
// Exactly one of *InstanceGroupManagerList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *InstanceGroupManagerList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceGroupManagersListCall) Do(opts ...googleapi.CallOption) (*InstanceGroupManagerList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupManagerList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of managed instance groups that are contained within the specified project and zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceGroupManagers.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers",
	//   "response": {
	//     "$ref": "InstanceGroupManagerList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstanceGroupManagersListCall) Pages(ctx context.Context, f func(*InstanceGroupManagerList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instanceGroupManagers.listManagedInstances":

type InstanceGroupManagersListManagedInstancesCall struct {
	s                    *Service
	project              string
	zone                 string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// ListManagedInstances: Lists all of the instances in the managed
// instance group. Each instance in the list has a currentAction, which
// indicates the action that the managed instance group is performing on
// the instance. For example, if the group is still creating an
// instance, the currentAction is CREATING. If a previous action failed,
// the list displays the errors for that failed action. (==
// suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) ListManagedInstances(project string, zone string, instanceGroupManager string) *InstanceGroupManagersListManagedInstancesCall {
	c := &InstanceGroupManagersListManagedInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstanceGroupManagersListManagedInstancesCall) Filter(filter string) *InstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstanceGroupManagersListManagedInstancesCall) MaxResults(maxResults int64) *InstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "order_by": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstanceGroupManagersListManagedInstancesCall) OrderBy(orderBy string) *InstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("order_by", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstanceGroupManagersListManagedInstancesCall) PageToken(pageToken string) *InstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersListManagedInstancesCall) Fields(s ...googleapi.Field) *InstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersListManagedInstancesCall) Context(ctx context.Context) *InstanceGroupManagersListManagedInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersListManagedInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersListManagedInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/listManagedInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.listManagedInstances" call.
// Exactly one of *InstanceGroupManagersListManagedInstancesResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *InstanceGroupManagersListManagedInstancesResponse.ServerResponse.Head
// er or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *InstanceGroupManagersListManagedInstancesCall) Do(opts ...googleapi.CallOption) (*InstanceGroupManagersListManagedInstancesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupManagersListManagedInstancesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists all of the instances in the managed instance group. Each instance in the list has a currentAction, which indicates the action that the managed instance group is performing on the instance. For example, if the group is still creating an instance, the currentAction is CREATING. If a previous action failed, the list displays the errors for that failed action. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.listManagedInstances",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "order_by": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/listManagedInstances",
	//   "response": {
	//     "$ref": "InstanceGroupManagersListManagedInstancesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.patch":

type InstanceGroupManagersPatchCall struct {
	s                    *Service
	project              string
	zone                 string
	instanceGroupManager string
	instancegroupmanager *InstanceGroupManager
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Patch: Updates a managed instance group using the information that
// you specify in the request. This operation is marked as DONE when the
// group is patched even if the instances in the group are still in the
// process of being patched. You must separately verify the status of
// the individual instances with the listManagedInstances method. This
// method supports PATCH semantics and uses the JSON merge patch format
// and processing rules. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) Patch(project string, zone string, instanceGroupManager string, instancegroupmanager *InstanceGroupManager) *InstanceGroupManagersPatchCall {
	c := &InstanceGroupManagersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	c.instancegroupmanager = instancegroupmanager
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersPatchCall) RequestId(requestId string) *InstanceGroupManagersPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersPatchCall) Fields(s ...googleapi.Field) *InstanceGroupManagersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersPatchCall) Context(ctx context.Context) *InstanceGroupManagersPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanager)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a managed instance group using the information that you specify in the request. This operation is marked as DONE when the group is patched even if the instances in the group are still in the process of being patched. You must separately verify the status of the individual instances with the listManagedInstances method. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.instanceGroupManagers.patch",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the instance group manager.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where you want to create the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}",
	//   "request": {
	//     "$ref": "InstanceGroupManager"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.recreateInstances":

type InstanceGroupManagersRecreateInstancesCall struct {
	s                                             *Service
	project                                       string
	zone                                          string
	instanceGroupManager                          string
	instancegroupmanagersrecreateinstancesrequest *InstanceGroupManagersRecreateInstancesRequest
	urlParams_                                    gensupport.URLParams
	ctx_                                          context.Context
	header_                                       http.Header
}

// RecreateInstances: Flags the specified instances in the managed
// instance group to be immediately recreated. The instances are deleted
// and recreated using the current instance template for the managed
// instance group. This operation is marked as DONE when the flag is set
// even if the instances have not yet been recreated. You must
// separately verify the status of the recreating action with the
// listmanagedinstances method.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or
// deleted.
//
// You can specify a maximum of 1000 instances with this method per
// request. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) RecreateInstances(project string, zone string, instanceGroupManager string, instancegroupmanagersrecreateinstancesrequest *InstanceGroupManagersRecreateInstancesRequest) *InstanceGroupManagersRecreateInstancesCall {
	c := &InstanceGroupManagersRecreateInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	c.instancegroupmanagersrecreateinstancesrequest = instancegroupmanagersrecreateinstancesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersRecreateInstancesCall) RequestId(requestId string) *InstanceGroupManagersRecreateInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersRecreateInstancesCall) Fields(s ...googleapi.Field) *InstanceGroupManagersRecreateInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersRecreateInstancesCall) Context(ctx context.Context) *InstanceGroupManagersRecreateInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersRecreateInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersRecreateInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanagersrecreateinstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/recreateInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.recreateInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersRecreateInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Flags the specified instances in the managed instance group to be immediately recreated. The instances are deleted and recreated using the current instance template for the managed instance group. This operation is marked as DONE when the flag is set even if the instances have not yet been recreated. You must separately verify the status of the recreating action with the listmanagedinstances method.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.\n\nYou can specify a maximum of 1000 instances with this method per request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.recreateInstances",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/recreateInstances",
	//   "request": {
	//     "$ref": "InstanceGroupManagersRecreateInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.resize":

type InstanceGroupManagersResizeCall struct {
	s                    *Service
	project              string
	zone                 string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Resize: Resizes the managed instance group. If you increase the size,
// the group creates new instances using the current instance template.
// If you decrease the size, the group deletes instances. The resize
// operation is marked DONE when the resize actions are scheduled even
// if the group has not yet added or deleted any instances. You must
// separately verify the status of the creating or deleting actions with
// the listmanagedinstances method.
//
// When resizing down, the instance group arbitrarily chooses the order
// in which VMs are deleted. The group takes into account some VM
// attributes when making the selection including:
//
// + The status of the VM instance. + The health of the VM instance. +
// The instance template version the VM is based on. + For regional
// managed instance groups, the location of the VM instance.
//
// This list is subject to change.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or deleted.
// (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) Resize(project string, zone string, instanceGroupManager string, size int64) *InstanceGroupManagersResizeCall {
	c := &InstanceGroupManagersResizeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	c.urlParams_.Set("size", fmt.Sprint(size))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersResizeCall) RequestId(requestId string) *InstanceGroupManagersResizeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersResizeCall) Fields(s ...googleapi.Field) *InstanceGroupManagersResizeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersResizeCall) Context(ctx context.Context) *InstanceGroupManagersResizeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersResizeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersResizeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/resize")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.resize" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersResizeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Resizes the managed instance group. If you increase the size, the group creates new instances using the current instance template. If you decrease the size, the group deletes instances. The resize operation is marked DONE when the resize actions are scheduled even if the group has not yet added or deleted any instances. You must separately verify the status of the creating or deleting actions with the listmanagedinstances method.\n\nWhen resizing down, the instance group arbitrarily chooses the order in which VMs are deleted. The group takes into account some VM attributes when making the selection including:\n\n+ The status of the VM instance. + The health of the VM instance. + The instance template version the VM is based on. + For regional managed instance groups, the location of the VM instance.\n\nThis list is subject to change.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.resize",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager",
	//     "size"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "size": {
	//       "description": "The number of running instances that the managed instance group should maintain at any given time. The group automatically adds or removes instances to maintain the number of instances specified by this parameter.",
	//       "format": "int32",
	//       "location": "query",
	//       "required": true,
	//       "type": "integer"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/resize",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.setInstanceTemplate":

type InstanceGroupManagersSetInstanceTemplateCall struct {
	s                                               *Service
	project                                         string
	zone                                            string
	instanceGroupManager                            string
	instancegroupmanagerssetinstancetemplaterequest *InstanceGroupManagersSetInstanceTemplateRequest
	urlParams_                                      gensupport.URLParams
	ctx_                                            context.Context
	header_                                         http.Header
}

// SetInstanceTemplate: Specifies the instance template to use when
// creating new instances in this group. The templates for existing
// instances in the group do not change unless you recreate them. (==
// suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupManagersService) SetInstanceTemplate(project string, zone string, instanceGroupManager string, instancegroupmanagerssetinstancetemplaterequest *InstanceGroupManagersSetInstanceTemplateRequest) *InstanceGroupManagersSetInstanceTemplateCall {
	c := &InstanceGroupManagersSetInstanceTemplateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	c.instancegroupmanagerssetinstancetemplaterequest = instancegroupmanagerssetinstancetemplaterequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersSetInstanceTemplateCall) RequestId(requestId string) *InstanceGroupManagersSetInstanceTemplateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersSetInstanceTemplateCall) Fields(s ...googleapi.Field) *InstanceGroupManagersSetInstanceTemplateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersSetInstanceTemplateCall) Context(ctx context.Context) *InstanceGroupManagersSetInstanceTemplateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersSetInstanceTemplateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersSetInstanceTemplateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanagerssetinstancetemplaterequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/setInstanceTemplate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.setInstanceTemplate" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersSetInstanceTemplateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Specifies the instance template to use when creating new instances in this group. The templates for existing instances in the group do not change unless you recreate them. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.setInstanceTemplate",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/setInstanceTemplate",
	//   "request": {
	//     "$ref": "InstanceGroupManagersSetInstanceTemplateRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroupManagers.setTargetPools":

type InstanceGroupManagersSetTargetPoolsCall struct {
	s                                          *Service
	project                                    string
	zone                                       string
	instanceGroupManager                       string
	instancegroupmanagerssettargetpoolsrequest *InstanceGroupManagersSetTargetPoolsRequest
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// SetTargetPools: Modifies the target pools to which all instances in
// this managed instance group are assigned. The target pools
// automatically apply to all of the instances in the managed instance
// group. This operation is marked DONE when you make the request even
// if the instances have not yet been added to their target pools. The
// change might take some time to apply to all of the instances in the
// group depending on the size of the group. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstanceGroupManagersService) SetTargetPools(project string, zone string, instanceGroupManager string, instancegroupmanagerssettargetpoolsrequest *InstanceGroupManagersSetTargetPoolsRequest) *InstanceGroupManagersSetTargetPoolsCall {
	c := &InstanceGroupManagersSetTargetPoolsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroupManager = instanceGroupManager
	c.instancegroupmanagerssettargetpoolsrequest = instancegroupmanagerssettargetpoolsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupManagersSetTargetPoolsCall) RequestId(requestId string) *InstanceGroupManagersSetTargetPoolsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupManagersSetTargetPoolsCall) Fields(s ...googleapi.Field) *InstanceGroupManagersSetTargetPoolsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupManagersSetTargetPoolsCall) Context(ctx context.Context) *InstanceGroupManagersSetTargetPoolsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupManagersSetTargetPoolsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupManagersSetTargetPoolsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanagerssettargetpoolsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/setTargetPools")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroupManagers.setTargetPools" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupManagersSetTargetPoolsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Modifies the target pools to which all instances in this managed instance group are assigned. The target pools automatically apply to all of the instances in the managed instance group. This operation is marked DONE when you make the request even if the instances have not yet been added to their target pools. The change might take some time to apply to all of the instances in the group depending on the size of the group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroupManagers.setTargetPools",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the managed instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}/setTargetPools",
	//   "request": {
	//     "$ref": "InstanceGroupManagersSetTargetPoolsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroups.addInstances":

type InstanceGroupsAddInstancesCall struct {
	s                                 *Service
	project                           string
	zone                              string
	instanceGroup                     string
	instancegroupsaddinstancesrequest *InstanceGroupsAddInstancesRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// AddInstances: Adds a list of instances to the specified instance
// group. All of the instances in the instance group must be in the same
// network/subnetwork. Read  Adding instances for more information. (==
// suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupsService) AddInstances(project string, zone string, instanceGroup string, instancegroupsaddinstancesrequest *InstanceGroupsAddInstancesRequest) *InstanceGroupsAddInstancesCall {
	c := &InstanceGroupsAddInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroup = instanceGroup
	c.instancegroupsaddinstancesrequest = instancegroupsaddinstancesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupsAddInstancesCall) RequestId(requestId string) *InstanceGroupsAddInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsAddInstancesCall) Fields(s ...googleapi.Field) *InstanceGroupsAddInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsAddInstancesCall) Context(ctx context.Context) *InstanceGroupsAddInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsAddInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsAddInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupsaddinstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups/{instanceGroup}/addInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"zone":          c.zone,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.addInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupsAddInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds a list of instances to the specified instance group. All of the instances in the instance group must be in the same network/subnetwork. Read  Adding instances for more information. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroups.addInstances",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "instanceGroup": {
	//       "description": "The name of the instance group where you are adding instances.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups/{instanceGroup}/addInstances",
	//   "request": {
	//     "$ref": "InstanceGroupsAddInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroups.aggregatedList":

type InstanceGroupsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of instance groups and sorts them
// by zone. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupsService) AggregatedList(project string) *InstanceGroupsAggregatedListCall {
	c := &InstanceGroupsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstanceGroupsAggregatedListCall) Filter(filter string) *InstanceGroupsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstanceGroupsAggregatedListCall) MaxResults(maxResults int64) *InstanceGroupsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstanceGroupsAggregatedListCall) OrderBy(orderBy string) *InstanceGroupsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstanceGroupsAggregatedListCall) PageToken(pageToken string) *InstanceGroupsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsAggregatedListCall) Fields(s ...googleapi.Field) *InstanceGroupsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceGroupsAggregatedListCall) IfNoneMatch(entityTag string) *InstanceGroupsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsAggregatedListCall) Context(ctx context.Context) *InstanceGroupsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/instanceGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.aggregatedList" call.
// Exactly one of *InstanceGroupAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *InstanceGroupAggregatedList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceGroupsAggregatedListCall) Do(opts ...googleapi.CallOption) (*InstanceGroupAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of instance groups and sorts them by zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceGroups.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/instanceGroups",
	//   "response": {
	//     "$ref": "InstanceGroupAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstanceGroupsAggregatedListCall) Pages(ctx context.Context, f func(*InstanceGroupAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instanceGroups.delete":

type InstanceGroupsDeleteCall struct {
	s             *Service
	project       string
	zone          string
	instanceGroup string
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Delete: Deletes the specified instance group. The instances in the
// group are not deleted. Note that instance group must not belong to a
// backend service. Read  Deleting an instance group for more
// information. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupsService) Delete(project string, zone string, instanceGroup string) *InstanceGroupsDeleteCall {
	c := &InstanceGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroup = instanceGroup
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupsDeleteCall) RequestId(requestId string) *InstanceGroupsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsDeleteCall) Fields(s ...googleapi.Field) *InstanceGroupsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsDeleteCall) Context(ctx context.Context) *InstanceGroupsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups/{instanceGroup}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"zone":          c.zone,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified instance group. The instances in the group are not deleted. Note that instance group must not belong to a backend service. Read  Deleting an instance group for more information. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.instanceGroups.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "instanceGroup": {
	//       "description": "The name of the instance group to delete.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups/{instanceGroup}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroups.get":

type InstanceGroupsGetCall struct {
	s             *Service
	project       string
	zone          string
	instanceGroup string
	urlParams_    gensupport.URLParams
	ifNoneMatch_  string
	ctx_          context.Context
	header_       http.Header
}

// Get: Returns the specified instance group. Gets a list of available
// instance groups by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstanceGroupsService) Get(project string, zone string, instanceGroup string) *InstanceGroupsGetCall {
	c := &InstanceGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroup = instanceGroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsGetCall) Fields(s ...googleapi.Field) *InstanceGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceGroupsGetCall) IfNoneMatch(entityTag string) *InstanceGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsGetCall) Context(ctx context.Context) *InstanceGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups/{instanceGroup}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"zone":          c.zone,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.get" call.
// Exactly one of *InstanceGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InstanceGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceGroupsGetCall) Do(opts ...googleapi.CallOption) (*InstanceGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified instance group. Gets a list of available instance groups by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceGroups.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "instanceGroup": {
	//       "description": "The name of the instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups/{instanceGroup}",
	//   "response": {
	//     "$ref": "InstanceGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instanceGroups.insert":

type InstanceGroupsInsertCall struct {
	s             *Service
	project       string
	zone          string
	instancegroup *InstanceGroup
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Creates an instance group in the specified project using the
// parameters that are included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstanceGroupsService) Insert(project string, zone string, instancegroup *InstanceGroup) *InstanceGroupsInsertCall {
	c := &InstanceGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instancegroup = instancegroup
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupsInsertCall) RequestId(requestId string) *InstanceGroupsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsInsertCall) Fields(s ...googleapi.Field) *InstanceGroupsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsInsertCall) Context(ctx context.Context) *InstanceGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an instance group in the specified project using the parameters that are included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroups.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where you want to create the instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups",
	//   "request": {
	//     "$ref": "InstanceGroup"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroups.list":

type InstanceGroupsListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of instance groups that are located in the
// specified project and zone. (== suppress_warning http-rest-shadowed
// ==)
func (r *InstanceGroupsService) List(project string, zone string) *InstanceGroupsListCall {
	c := &InstanceGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstanceGroupsListCall) Filter(filter string) *InstanceGroupsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstanceGroupsListCall) MaxResults(maxResults int64) *InstanceGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstanceGroupsListCall) OrderBy(orderBy string) *InstanceGroupsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstanceGroupsListCall) PageToken(pageToken string) *InstanceGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsListCall) Fields(s ...googleapi.Field) *InstanceGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceGroupsListCall) IfNoneMatch(entityTag string) *InstanceGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsListCall) Context(ctx context.Context) *InstanceGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.list" call.
// Exactly one of *InstanceGroupList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InstanceGroupList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceGroupsListCall) Do(opts ...googleapi.CallOption) (*InstanceGroupList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of instance groups that are located in the specified project and zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceGroups.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups",
	//   "response": {
	//     "$ref": "InstanceGroupList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstanceGroupsListCall) Pages(ctx context.Context, f func(*InstanceGroupList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instanceGroups.listInstances":

type InstanceGroupsListInstancesCall struct {
	s                                  *Service
	project                            string
	zone                               string
	instanceGroup                      string
	instancegroupslistinstancesrequest *InstanceGroupsListInstancesRequest
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// ListInstances: Lists the instances in the specified instance group.
// (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupsService) ListInstances(project string, zone string, instanceGroup string, instancegroupslistinstancesrequest *InstanceGroupsListInstancesRequest) *InstanceGroupsListInstancesCall {
	c := &InstanceGroupsListInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroup = instanceGroup
	c.instancegroupslistinstancesrequest = instancegroupslistinstancesrequest
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstanceGroupsListInstancesCall) Filter(filter string) *InstanceGroupsListInstancesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstanceGroupsListInstancesCall) MaxResults(maxResults int64) *InstanceGroupsListInstancesCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstanceGroupsListInstancesCall) OrderBy(orderBy string) *InstanceGroupsListInstancesCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstanceGroupsListInstancesCall) PageToken(pageToken string) *InstanceGroupsListInstancesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsListInstancesCall) Fields(s ...googleapi.Field) *InstanceGroupsListInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsListInstancesCall) Context(ctx context.Context) *InstanceGroupsListInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsListInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsListInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupslistinstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups/{instanceGroup}/listInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"zone":          c.zone,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.listInstances" call.
// Exactly one of *InstanceGroupsListInstances or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *InstanceGroupsListInstances.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceGroupsListInstancesCall) Do(opts ...googleapi.CallOption) (*InstanceGroupsListInstances, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupsListInstances{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists the instances in the specified instance group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroups.listInstances",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "instanceGroup": {
	//       "description": "The name of the instance group from which you want to generate a list of included instances.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups/{instanceGroup}/listInstances",
	//   "request": {
	//     "$ref": "InstanceGroupsListInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "InstanceGroupsListInstances"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstanceGroupsListInstancesCall) Pages(ctx context.Context, f func(*InstanceGroupsListInstances) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instanceGroups.removeInstances":

type InstanceGroupsRemoveInstancesCall struct {
	s                                    *Service
	project                              string
	zone                                 string
	instanceGroup                        string
	instancegroupsremoveinstancesrequest *InstanceGroupsRemoveInstancesRequest
	urlParams_                           gensupport.URLParams
	ctx_                                 context.Context
	header_                              http.Header
}

// RemoveInstances: Removes one or more instances from the specified
// instance group, but does not delete those instances.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration before the VM instance is removed or deleted. (==
// suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupsService) RemoveInstances(project string, zone string, instanceGroup string, instancegroupsremoveinstancesrequest *InstanceGroupsRemoveInstancesRequest) *InstanceGroupsRemoveInstancesCall {
	c := &InstanceGroupsRemoveInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroup = instanceGroup
	c.instancegroupsremoveinstancesrequest = instancegroupsremoveinstancesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupsRemoveInstancesCall) RequestId(requestId string) *InstanceGroupsRemoveInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsRemoveInstancesCall) Fields(s ...googleapi.Field) *InstanceGroupsRemoveInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsRemoveInstancesCall) Context(ctx context.Context) *InstanceGroupsRemoveInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsRemoveInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsRemoveInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupsremoveinstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups/{instanceGroup}/removeInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"zone":          c.zone,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.removeInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupsRemoveInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Removes one or more instances from the specified instance group, but does not delete those instances.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration before the VM instance is removed or deleted. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroups.removeInstances",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "instanceGroup": {
	//       "description": "The name of the instance group where the specified instances will be removed.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups/{instanceGroup}/removeInstances",
	//   "request": {
	//     "$ref": "InstanceGroupsRemoveInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceGroups.setNamedPorts":

type InstanceGroupsSetNamedPortsCall struct {
	s                                  *Service
	project                            string
	zone                               string
	instanceGroup                      string
	instancegroupssetnamedportsrequest *InstanceGroupsSetNamedPortsRequest
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// SetNamedPorts: Sets the named ports for the specified instance group.
// (== suppress_warning http-rest-shadowed ==)
func (r *InstanceGroupsService) SetNamedPorts(project string, zone string, instanceGroup string, instancegroupssetnamedportsrequest *InstanceGroupsSetNamedPortsRequest) *InstanceGroupsSetNamedPortsCall {
	c := &InstanceGroupsSetNamedPortsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instanceGroup = instanceGroup
	c.instancegroupssetnamedportsrequest = instancegroupssetnamedportsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceGroupsSetNamedPortsCall) RequestId(requestId string) *InstanceGroupsSetNamedPortsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceGroupsSetNamedPortsCall) Fields(s ...googleapi.Field) *InstanceGroupsSetNamedPortsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceGroupsSetNamedPortsCall) Context(ctx context.Context) *InstanceGroupsSetNamedPortsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceGroupsSetNamedPortsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceGroupsSetNamedPortsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupssetnamedportsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instanceGroups/{instanceGroup}/setNamedPorts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"zone":          c.zone,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceGroups.setNamedPorts" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceGroupsSetNamedPortsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the named ports for the specified instance group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceGroups.setNamedPorts",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "instanceGroup": {
	//       "description": "The name of the instance group where the named ports are updated.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the instance group is located.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instanceGroups/{instanceGroup}/setNamedPorts",
	//   "request": {
	//     "$ref": "InstanceGroupsSetNamedPortsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceTemplates.delete":

type InstanceTemplatesDeleteCall struct {
	s                *Service
	project          string
	instanceTemplate string
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Delete: Deletes the specified instance template. Deleting an instance
// template is permanent and cannot be undone. It is not possible to
// delete templates that are already in use by a managed instance group.
// (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instanceTemplates/delete
func (r *InstanceTemplatesService) Delete(project string, instanceTemplate string) *InstanceTemplatesDeleteCall {
	c := &InstanceTemplatesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.instanceTemplate = instanceTemplate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceTemplatesDeleteCall) RequestId(requestId string) *InstanceTemplatesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceTemplatesDeleteCall) Fields(s ...googleapi.Field) *InstanceTemplatesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceTemplatesDeleteCall) Context(ctx context.Context) *InstanceTemplatesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceTemplatesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceTemplatesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates/{instanceTemplate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"instanceTemplate": c.instanceTemplate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceTemplates.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceTemplatesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified instance template. Deleting an instance template is permanent and cannot be undone. It is not possible to delete templates that are already in use by a managed instance group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.instanceTemplates.delete",
	//   "parameterOrder": [
	//     "project",
	//     "instanceTemplate"
	//   ],
	//   "parameters": {
	//     "instanceTemplate": {
	//       "description": "The name of the instance template to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/instanceTemplates/{instanceTemplate}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceTemplates.get":

type InstanceTemplatesGetCall struct {
	s                *Service
	project          string
	instanceTemplate string
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// Get: Returns the specified instance template. Gets a list of
// available instance templates by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instanceTemplates/get
func (r *InstanceTemplatesService) Get(project string, instanceTemplate string) *InstanceTemplatesGetCall {
	c := &InstanceTemplatesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.instanceTemplate = instanceTemplate
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceTemplatesGetCall) Fields(s ...googleapi.Field) *InstanceTemplatesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceTemplatesGetCall) IfNoneMatch(entityTag string) *InstanceTemplatesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceTemplatesGetCall) Context(ctx context.Context) *InstanceTemplatesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceTemplatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceTemplatesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates/{instanceTemplate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"instanceTemplate": c.instanceTemplate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceTemplates.get" call.
// Exactly one of *InstanceTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InstanceTemplate.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceTemplatesGetCall) Do(opts ...googleapi.CallOption) (*InstanceTemplate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceTemplate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified instance template. Gets a list of available instance templates by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceTemplates.get",
	//   "parameterOrder": [
	//     "project",
	//     "instanceTemplate"
	//   ],
	//   "parameters": {
	//     "instanceTemplate": {
	//       "description": "The name of the instance template.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/instanceTemplates/{instanceTemplate}",
	//   "response": {
	//     "$ref": "InstanceTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instanceTemplates.getIamPolicy":

type InstanceTemplatesGetIamPolicyCall struct {
	s            *Service
	project      string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstanceTemplatesService) GetIamPolicy(project string, resource string) *InstanceTemplatesGetIamPolicyCall {
	c := &InstanceTemplatesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceTemplatesGetIamPolicyCall) Fields(s ...googleapi.Field) *InstanceTemplatesGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceTemplatesGetIamPolicyCall) IfNoneMatch(entityTag string) *InstanceTemplatesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceTemplatesGetIamPolicyCall) Context(ctx context.Context) *InstanceTemplatesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceTemplatesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceTemplatesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceTemplates.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *InstanceTemplatesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceTemplates.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/instanceTemplates/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instanceTemplates.insert":

type InstanceTemplatesInsertCall struct {
	s                *Service
	project          string
	instancetemplate *InstanceTemplate
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Insert: Creates an instance template in the specified project using
// the data that is included in the request. If you are creating a new
// template to update an existing instance group, your new instance
// template must use the same network or, if applicable, the same
// subnetwork as the original template. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instanceTemplates/insert
func (r *InstanceTemplatesService) Insert(project string, instancetemplate *InstanceTemplate) *InstanceTemplatesInsertCall {
	c := &InstanceTemplatesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.instancetemplate = instancetemplate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstanceTemplatesInsertCall) RequestId(requestId string) *InstanceTemplatesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceTemplatesInsertCall) Fields(s ...googleapi.Field) *InstanceTemplatesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceTemplatesInsertCall) Context(ctx context.Context) *InstanceTemplatesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceTemplatesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceTemplatesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancetemplate)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceTemplates.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstanceTemplatesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an instance template in the specified project using the data that is included in the request. If you are creating a new template to update an existing instance group, your new instance template must use the same network or, if applicable, the same subnetwork as the original template. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceTemplates.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/instanceTemplates",
	//   "request": {
	//     "$ref": "InstanceTemplate"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceTemplates.list":

type InstanceTemplatesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of instance templates that are contained
// within the specified project. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instanceTemplates/list
func (r *InstanceTemplatesService) List(project string) *InstanceTemplatesListCall {
	c := &InstanceTemplatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstanceTemplatesListCall) Filter(filter string) *InstanceTemplatesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstanceTemplatesListCall) MaxResults(maxResults int64) *InstanceTemplatesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstanceTemplatesListCall) OrderBy(orderBy string) *InstanceTemplatesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstanceTemplatesListCall) PageToken(pageToken string) *InstanceTemplatesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceTemplatesListCall) Fields(s ...googleapi.Field) *InstanceTemplatesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstanceTemplatesListCall) IfNoneMatch(entityTag string) *InstanceTemplatesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceTemplatesListCall) Context(ctx context.Context) *InstanceTemplatesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceTemplatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceTemplatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceTemplates.list" call.
// Exactly one of *InstanceTemplateList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InstanceTemplateList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceTemplatesListCall) Do(opts ...googleapi.CallOption) (*InstanceTemplateList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceTemplateList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of instance templates that are contained within the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instanceTemplates.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/instanceTemplates",
	//   "response": {
	//     "$ref": "InstanceTemplateList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstanceTemplatesListCall) Pages(ctx context.Context, f func(*InstanceTemplateList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instanceTemplates.setIamPolicy":

type InstanceTemplatesSetIamPolicyCall struct {
	s                      *Service
	project                string
	resource               string
	globalsetpolicyrequest *GlobalSetPolicyRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstanceTemplatesService) SetIamPolicy(project string, resource string, globalsetpolicyrequest *GlobalSetPolicyRequest) *InstanceTemplatesSetIamPolicyCall {
	c := &InstanceTemplatesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.globalsetpolicyrequest = globalsetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceTemplatesSetIamPolicyCall) Fields(s ...googleapi.Field) *InstanceTemplatesSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceTemplatesSetIamPolicyCall) Context(ctx context.Context) *InstanceTemplatesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceTemplatesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceTemplatesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.globalsetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceTemplates.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *InstanceTemplatesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceTemplates.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/instanceTemplates/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "GlobalSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instanceTemplates.testIamPermissions":

type InstanceTemplatesTestIamPermissionsCall struct {
	s                      *Service
	project                string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *InstanceTemplatesService) TestIamPermissions(project string, resource string, testpermissionsrequest *TestPermissionsRequest) *InstanceTemplatesTestIamPermissionsCall {
	c := &InstanceTemplatesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstanceTemplatesTestIamPermissionsCall) Fields(s ...googleapi.Field) *InstanceTemplatesTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstanceTemplatesTestIamPermissionsCall) Context(ctx context.Context) *InstanceTemplatesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstanceTemplatesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstanceTemplatesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instanceTemplates.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstanceTemplatesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instanceTemplates.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/instanceTemplates/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instances.addAccessConfig":

type InstancesAddAccessConfigCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	accessconfig *AccessConfig
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// AddAccessConfig: Adds an access config to an instance's network
// interface. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/addAccessConfig
func (r *InstancesService) AddAccessConfig(project string, zone string, instance string, networkInterface string, accessconfig *AccessConfig) *InstancesAddAccessConfigCall {
	c := &InstancesAddAccessConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.urlParams_.Set("networkInterface", networkInterface)
	c.accessconfig = accessconfig
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesAddAccessConfigCall) RequestId(requestId string) *InstancesAddAccessConfigCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesAddAccessConfigCall) Fields(s ...googleapi.Field) *InstancesAddAccessConfigCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesAddAccessConfigCall) Context(ctx context.Context) *InstancesAddAccessConfigCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesAddAccessConfigCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesAddAccessConfigCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.accessconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/addAccessConfig")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.addAccessConfig" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesAddAccessConfigCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds an access config to an instance's network interface. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.addAccessConfig",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance",
	//     "networkInterface"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "The instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "networkInterface": {
	//       "description": "The name of the network interface to add to this instance.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/addAccessConfig",
	//   "request": {
	//     "$ref": "AccessConfig"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.aggregatedList":

type InstancesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves aggregated list of all of the instances in
// your project across all regions and zones. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/aggregatedList
func (r *InstancesService) AggregatedList(project string) *InstancesAggregatedListCall {
	c := &InstancesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstancesAggregatedListCall) Filter(filter string) *InstancesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstancesAggregatedListCall) MaxResults(maxResults int64) *InstancesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstancesAggregatedListCall) OrderBy(orderBy string) *InstancesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstancesAggregatedListCall) PageToken(pageToken string) *InstancesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesAggregatedListCall) Fields(s ...googleapi.Field) *InstancesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesAggregatedListCall) IfNoneMatch(entityTag string) *InstancesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesAggregatedListCall) Context(ctx context.Context) *InstancesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.aggregatedList" call.
// Exactly one of *InstanceAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InstanceAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstancesAggregatedListCall) Do(opts ...googleapi.CallOption) (*InstanceAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves aggregated list of all of the instances in your project across all regions and zones. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/instances",
	//   "response": {
	//     "$ref": "InstanceAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstancesAggregatedListCall) Pages(ctx context.Context, f func(*InstanceAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instances.attachDisk":

type InstancesAttachDiskCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	attacheddisk *AttachedDisk
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// AttachDisk: Attaches an existing Disk resource to an instance. You
// must first create the disk before you can attach it. It is not
// possible to create and attach a disk at the same time. For more
// information, read Adding a persistent disk to your instance. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/attachDisk
func (r *InstancesService) AttachDisk(project string, zone string, instance string, attacheddisk *AttachedDisk) *InstancesAttachDiskCall {
	c := &InstancesAttachDiskCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.attacheddisk = attacheddisk
	return c
}

// ForceAttach sets the optional parameter "forceAttach": Whether to
// force attach the disk even if it's currently attached to another
// instance.
func (c *InstancesAttachDiskCall) ForceAttach(forceAttach bool) *InstancesAttachDiskCall {
	c.urlParams_.Set("forceAttach", fmt.Sprint(forceAttach))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesAttachDiskCall) RequestId(requestId string) *InstancesAttachDiskCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesAttachDiskCall) Fields(s ...googleapi.Field) *InstancesAttachDiskCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesAttachDiskCall) Context(ctx context.Context) *InstancesAttachDiskCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesAttachDiskCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesAttachDiskCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.attacheddisk)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/attachDisk")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.attachDisk" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesAttachDiskCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Attaches an existing Disk resource to an instance. You must first create the disk before you can attach it. It is not possible to create and attach a disk at the same time. For more information, read Adding a persistent disk to your instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.attachDisk",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "forceAttach": {
	//       "description": "Whether to force attach the disk even if it's currently attached to another instance.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "instance": {
	//       "description": "The instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/attachDisk",
	//   "request": {
	//     "$ref": "AttachedDisk"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.delete":

type InstancesDeleteCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified Instance resource. For more
// information, see Stopping or Deleting an Instance. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/delete
func (r *InstancesService) Delete(project string, zone string, instance string) *InstancesDeleteCall {
	c := &InstancesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesDeleteCall) RequestId(requestId string) *InstancesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesDeleteCall) Fields(s ...googleapi.Field) *InstancesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesDeleteCall) Context(ctx context.Context) *InstancesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified Instance resource. For more information, see Stopping or Deleting an Instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.instances.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.deleteAccessConfig":

type InstancesDeleteAccessConfigCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DeleteAccessConfig: Deletes an access config from an instance's
// network interface. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/deleteAccessConfig
func (r *InstancesService) DeleteAccessConfig(project string, zone string, instance string, accessConfig string, networkInterface string) *InstancesDeleteAccessConfigCall {
	c := &InstancesDeleteAccessConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.urlParams_.Set("accessConfig", accessConfig)
	c.urlParams_.Set("networkInterface", networkInterface)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesDeleteAccessConfigCall) RequestId(requestId string) *InstancesDeleteAccessConfigCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesDeleteAccessConfigCall) Fields(s ...googleapi.Field) *InstancesDeleteAccessConfigCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesDeleteAccessConfigCall) Context(ctx context.Context) *InstancesDeleteAccessConfigCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesDeleteAccessConfigCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesDeleteAccessConfigCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/deleteAccessConfig")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.deleteAccessConfig" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesDeleteAccessConfigCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an access config from an instance's network interface. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.deleteAccessConfig",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance",
	//     "accessConfig",
	//     "networkInterface"
	//   ],
	//   "parameters": {
	//     "accessConfig": {
	//       "description": "The name of the access config to delete.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "instance": {
	//       "description": "The instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "networkInterface": {
	//       "description": "The name of the network interface.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/deleteAccessConfig",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.detachDisk":

type InstancesDetachDiskCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DetachDisk: Detaches a disk from an instance. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/detachDisk
func (r *InstancesService) DetachDisk(project string, zone string, instance string, deviceName string) *InstancesDetachDiskCall {
	c := &InstancesDetachDiskCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.urlParams_.Set("deviceName", deviceName)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesDetachDiskCall) RequestId(requestId string) *InstancesDetachDiskCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesDetachDiskCall) Fields(s ...googleapi.Field) *InstancesDetachDiskCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesDetachDiskCall) Context(ctx context.Context) *InstancesDetachDiskCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesDetachDiskCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesDetachDiskCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/detachDisk")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.detachDisk" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesDetachDiskCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Detaches a disk from an instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.detachDisk",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance",
	//     "deviceName"
	//   ],
	//   "parameters": {
	//     "deviceName": {
	//       "description": "The device name of the disk to detach. Make a get() request on the instance to view currently attached disks and device names.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "instance": {
	//       "description": "Instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/detachDisk",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.get":

type InstancesGetCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified Instance resource. Gets a list of
// available instances by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/get
func (r *InstancesService) Get(project string, zone string, instance string) *InstancesGetCall {
	c := &InstancesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesGetCall) Fields(s ...googleapi.Field) *InstancesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesGetCall) IfNoneMatch(entityTag string) *InstancesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesGetCall) Context(ctx context.Context) *InstancesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.get" call.
// Exactly one of *Instance or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Instance.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesGetCall) Do(opts ...googleapi.CallOption) (*Instance, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Instance{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified Instance resource. Gets a list of available instances by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}",
	//   "response": {
	//     "$ref": "Instance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instances.getGuestAttributes":

type InstancesGetGuestAttributesCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetGuestAttributes: Returns the specified guest attributes entry. (==
// suppress_warning http-rest-shadowed ==)
func (r *InstancesService) GetGuestAttributes(project string, zone string, instance string) *InstancesGetGuestAttributesCall {
	c := &InstancesGetGuestAttributesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// QueryPath sets the optional parameter "queryPath": Specifies the
// guest attributes path to be queried.
func (c *InstancesGetGuestAttributesCall) QueryPath(queryPath string) *InstancesGetGuestAttributesCall {
	c.urlParams_.Set("queryPath", queryPath)
	return c
}

// VariableKey sets the optional parameter "variableKey": Specifies the
// key for the guest attributes entry.
func (c *InstancesGetGuestAttributesCall) VariableKey(variableKey string) *InstancesGetGuestAttributesCall {
	c.urlParams_.Set("variableKey", variableKey)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesGetGuestAttributesCall) Fields(s ...googleapi.Field) *InstancesGetGuestAttributesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesGetGuestAttributesCall) IfNoneMatch(entityTag string) *InstancesGetGuestAttributesCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesGetGuestAttributesCall) Context(ctx context.Context) *InstancesGetGuestAttributesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesGetGuestAttributesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesGetGuestAttributesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/getGuestAttributes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.getGuestAttributes" call.
// Exactly one of *GuestAttributes or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *GuestAttributes.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstancesGetGuestAttributesCall) Do(opts ...googleapi.CallOption) (*GuestAttributes, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GuestAttributes{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified guest attributes entry. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.getGuestAttributes",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "queryPath": {
	//       "description": "Specifies the guest attributes path to be queried.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "variableKey": {
	//       "description": "Specifies the key for the guest attributes entry.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/getGuestAttributes",
	//   "response": {
	//     "$ref": "GuestAttributes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instances.getIamPolicy":

type InstancesGetIamPolicyCall struct {
	s            *Service
	project      string
	zone         string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstancesService) GetIamPolicy(project string, zone string, resource string) *InstancesGetIamPolicyCall {
	c := &InstancesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesGetIamPolicyCall) Fields(s ...googleapi.Field) *InstancesGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesGetIamPolicyCall) IfNoneMatch(entityTag string) *InstancesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesGetIamPolicyCall) Context(ctx context.Context) *InstancesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *InstancesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instances.getSerialPortOutput":

type InstancesGetSerialPortOutputCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetSerialPortOutput: Returns the last 1 MB of serial port output from
// the specified instance. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/getSerialPortOutput
func (r *InstancesService) GetSerialPortOutput(project string, zone string, instance string) *InstancesGetSerialPortOutputCall {
	c := &InstancesGetSerialPortOutputCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// Port sets the optional parameter "port": Specifies which COM or
// serial port to retrieve data from.
func (c *InstancesGetSerialPortOutputCall) Port(port int64) *InstancesGetSerialPortOutputCall {
	c.urlParams_.Set("port", fmt.Sprint(port))
	return c
}

// Start sets the optional parameter "start": Returns output starting
// from a specific byte position. Use this to page through output when
// the output is too large to return in a single request. For the
// initial request, leave this field unspecified. For subsequent calls,
// this field should be set to the next value returned in the previous
// call.
func (c *InstancesGetSerialPortOutputCall) Start(start int64) *InstancesGetSerialPortOutputCall {
	c.urlParams_.Set("start", fmt.Sprint(start))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesGetSerialPortOutputCall) Fields(s ...googleapi.Field) *InstancesGetSerialPortOutputCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesGetSerialPortOutputCall) IfNoneMatch(entityTag string) *InstancesGetSerialPortOutputCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesGetSerialPortOutputCall) Context(ctx context.Context) *InstancesGetSerialPortOutputCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesGetSerialPortOutputCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesGetSerialPortOutputCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/serialPort")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.getSerialPortOutput" call.
// Exactly one of *SerialPortOutput or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SerialPortOutput.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstancesGetSerialPortOutputCall) Do(opts ...googleapi.CallOption) (*SerialPortOutput, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SerialPortOutput{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the last 1 MB of serial port output from the specified instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.getSerialPortOutput",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "port": {
	//       "default": "1",
	//       "description": "Specifies which COM or serial port to retrieve data from.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "4",
	//       "minimum": "1",
	//       "type": "integer"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "start": {
	//       "description": "Returns output starting from a specific byte position. Use this to page through output when the output is too large to return in a single request. For the initial request, leave this field unspecified. For subsequent calls, this field should be set to the next value returned in the previous call.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/serialPort",
	//   "response": {
	//     "$ref": "SerialPortOutput"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instances.getShieldedInstanceIdentity":

type InstancesGetShieldedInstanceIdentityCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetShieldedInstanceIdentity: Returns the Shielded Instance Identity
// of an instance (== suppress_warning http-rest-shadowed ==)
func (r *InstancesService) GetShieldedInstanceIdentity(project string, zone string, instance string) *InstancesGetShieldedInstanceIdentityCall {
	c := &InstancesGetShieldedInstanceIdentityCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesGetShieldedInstanceIdentityCall) Fields(s ...googleapi.Field) *InstancesGetShieldedInstanceIdentityCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesGetShieldedInstanceIdentityCall) IfNoneMatch(entityTag string) *InstancesGetShieldedInstanceIdentityCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesGetShieldedInstanceIdentityCall) Context(ctx context.Context) *InstancesGetShieldedInstanceIdentityCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesGetShieldedInstanceIdentityCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesGetShieldedInstanceIdentityCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/getShieldedInstanceIdentity")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.getShieldedInstanceIdentity" call.
// Exactly one of *ShieldedInstanceIdentity or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ShieldedInstanceIdentity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstancesGetShieldedInstanceIdentityCall) Do(opts ...googleapi.CallOption) (*ShieldedInstanceIdentity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ShieldedInstanceIdentity{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the Shielded Instance Identity of an instance (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.getShieldedInstanceIdentity",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name or id of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/getShieldedInstanceIdentity",
	//   "response": {
	//     "$ref": "ShieldedInstanceIdentity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instances.insert":

type InstancesInsertCall struct {
	s          *Service
	project    string
	zone       string
	instance   *Instance
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates an instance resource in the specified project using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/insert
func (r *InstancesService) Insert(project string, zone string, instance *Instance) *InstancesInsertCall {
	c := &InstancesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesInsertCall) RequestId(requestId string) *InstancesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// SourceInstanceTemplate sets the optional parameter
// "sourceInstanceTemplate": Specifies instance template to create the
// instance.
//
// This field is optional. It can be a full or partial URL. For example,
// the following are all valid URLs to an instance template:
// -
// https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/instanceTemplate
// - projects/project/global/instanceTemplates/instanceTemplate
// - global/instanceTemplates/instanceTemplate
func (c *InstancesInsertCall) SourceInstanceTemplate(sourceInstanceTemplate string) *InstancesInsertCall {
	c.urlParams_.Set("sourceInstanceTemplate", sourceInstanceTemplate)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesInsertCall) Fields(s ...googleapi.Field) *InstancesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesInsertCall) Context(ctx context.Context) *InstancesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instance)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an instance resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sourceInstanceTemplate": {
	//       "description": "Specifies instance template to create the instance.\n\nThis field is optional. It can be a full or partial URL. For example, the following are all valid URLs to an instance template:  \n- https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/instanceTemplate \n- projects/project/global/instanceTemplates/instanceTemplate \n- global/instanceTemplates/instanceTemplate",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances",
	//   "request": {
	//     "$ref": "Instance"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.list":

type InstancesListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of instances contained within the specified
// zone. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/list
func (r *InstancesService) List(project string, zone string) *InstancesListCall {
	c := &InstancesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstancesListCall) Filter(filter string) *InstancesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstancesListCall) MaxResults(maxResults int64) *InstancesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstancesListCall) OrderBy(orderBy string) *InstancesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstancesListCall) PageToken(pageToken string) *InstancesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesListCall) Fields(s ...googleapi.Field) *InstancesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesListCall) IfNoneMatch(entityTag string) *InstancesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesListCall) Context(ctx context.Context) *InstancesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.list" call.
// Exactly one of *InstanceList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InstanceList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesListCall) Do(opts ...googleapi.CallOption) (*InstanceList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of instances contained within the specified zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances",
	//   "response": {
	//     "$ref": "InstanceList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstancesListCall) Pages(ctx context.Context, f func(*InstanceList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instances.listReferrers":

type InstancesListReferrersCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListReferrers: Retrieves the list of referrers to instances contained
// within the specified zone. For more information, read Viewing
// Referrers to VM Instances. (== suppress_warning http-rest-shadowed
// ==)
func (r *InstancesService) ListReferrers(project string, zone string, instance string) *InstancesListReferrersCall {
	c := &InstancesListReferrersCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InstancesListReferrersCall) Filter(filter string) *InstancesListReferrersCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InstancesListReferrersCall) MaxResults(maxResults int64) *InstancesListReferrersCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InstancesListReferrersCall) OrderBy(orderBy string) *InstancesListReferrersCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InstancesListReferrersCall) PageToken(pageToken string) *InstancesListReferrersCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesListReferrersCall) Fields(s ...googleapi.Field) *InstancesListReferrersCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InstancesListReferrersCall) IfNoneMatch(entityTag string) *InstancesListReferrersCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesListReferrersCall) Context(ctx context.Context) *InstancesListReferrersCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesListReferrersCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesListReferrersCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/referrers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.listReferrers" call.
// Exactly one of *InstanceListReferrers or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InstanceListReferrers.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstancesListReferrersCall) Do(opts ...googleapi.CallOption) (*InstanceListReferrers, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceListReferrers{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of referrers to instances contained within the specified zone. For more information, read Viewing Referrers to VM Instances. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.instances.listReferrers",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "instance": {
	//       "description": "Name of the target instance scoping this request, or '-' if the request should span over all instances in the container.",
	//       "location": "path",
	//       "pattern": "-|[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/referrers",
	//   "response": {
	//     "$ref": "InstanceListReferrers"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InstancesListReferrersCall) Pages(ctx context.Context, f func(*InstanceListReferrers) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.instances.reset":

type InstancesResetCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Reset: Performs a reset on the instance. This is a hard reset the VM
// does not do a graceful shutdown. For more information, see Resetting
// an instance. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/reset
func (r *InstancesService) Reset(project string, zone string, instance string) *InstancesResetCall {
	c := &InstancesResetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesResetCall) RequestId(requestId string) *InstancesResetCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesResetCall) Fields(s ...googleapi.Field) *InstancesResetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesResetCall) Context(ctx context.Context) *InstancesResetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesResetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesResetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/reset")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.reset" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesResetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Performs a reset on the instance. This is a hard reset the VM does not do a graceful shutdown. For more information, see Resetting an instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.reset",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/reset",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setDeletionProtection":

type InstancesSetDeletionProtectionCall struct {
	s          *Service
	project    string
	zone       string
	resource   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SetDeletionProtection: Sets deletion protection on the instance. (==
// suppress_warning http-rest-shadowed ==)
func (r *InstancesService) SetDeletionProtection(project string, zone string, resource string) *InstancesSetDeletionProtectionCall {
	c := &InstancesSetDeletionProtectionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	return c
}

// DeletionProtection sets the optional parameter "deletionProtection":
// Whether the resource should be protected against deletion.
func (c *InstancesSetDeletionProtectionCall) DeletionProtection(deletionProtection bool) *InstancesSetDeletionProtectionCall {
	c.urlParams_.Set("deletionProtection", fmt.Sprint(deletionProtection))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetDeletionProtectionCall) RequestId(requestId string) *InstancesSetDeletionProtectionCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetDeletionProtectionCall) Fields(s ...googleapi.Field) *InstancesSetDeletionProtectionCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetDeletionProtectionCall) Context(ctx context.Context) *InstancesSetDeletionProtectionCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetDeletionProtectionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetDeletionProtectionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{resource}/setDeletionProtection")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setDeletionProtection" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetDeletionProtectionCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets deletion protection on the instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setDeletionProtection",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "deletionProtection": {
	//       "default": "true",
	//       "description": "Whether the resource should be protected against deletion.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{resource}/setDeletionProtection",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setDiskAutoDelete":

type InstancesSetDiskAutoDeleteCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SetDiskAutoDelete: Sets the auto-delete flag for a disk attached to
// an instance. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/setDiskAutoDelete
func (r *InstancesService) SetDiskAutoDelete(project string, zone string, instance string, autoDelete bool, deviceName string) *InstancesSetDiskAutoDeleteCall {
	c := &InstancesSetDiskAutoDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.urlParams_.Set("autoDelete", fmt.Sprint(autoDelete))
	c.urlParams_.Set("deviceName", deviceName)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetDiskAutoDeleteCall) RequestId(requestId string) *InstancesSetDiskAutoDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetDiskAutoDeleteCall) Fields(s ...googleapi.Field) *InstancesSetDiskAutoDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetDiskAutoDeleteCall) Context(ctx context.Context) *InstancesSetDiskAutoDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetDiskAutoDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetDiskAutoDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setDiskAutoDelete")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setDiskAutoDelete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetDiskAutoDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the auto-delete flag for a disk attached to an instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setDiskAutoDelete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance",
	//     "autoDelete",
	//     "deviceName"
	//   ],
	//   "parameters": {
	//     "autoDelete": {
	//       "description": "Whether to auto-delete the disk when the instance is deleted.",
	//       "location": "query",
	//       "required": true,
	//       "type": "boolean"
	//     },
	//     "deviceName": {
	//       "description": "The device name of the disk to modify. Make a get() request on the instance to view currently attached disks and device names.",
	//       "location": "query",
	//       "pattern": "\\w[\\w.-]{0,254}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "instance": {
	//       "description": "The instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setDiskAutoDelete",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setIamPolicy":

type InstancesSetIamPolicyCall struct {
	s                    *Service
	project              string
	zone                 string
	resource             string
	zonesetpolicyrequest *ZoneSetPolicyRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstancesService) SetIamPolicy(project string, zone string, resource string, zonesetpolicyrequest *ZoneSetPolicyRequest) *InstancesSetIamPolicyCall {
	c := &InstancesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.zonesetpolicyrequest = zonesetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetIamPolicyCall) Fields(s ...googleapi.Field) *InstancesSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetIamPolicyCall) Context(ctx context.Context) *InstancesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.zonesetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *InstancesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "ZoneSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setLabels":

type InstancesSetLabelsCall struct {
	s                         *Service
	project                   string
	zone                      string
	instance                  string
	instancessetlabelsrequest *InstancesSetLabelsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// SetLabels: Sets labels on an instance. To learn more about labels,
// read the Labeling Resources documentation. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstancesService) SetLabels(project string, zone string, instance string, instancessetlabelsrequest *InstancesSetLabelsRequest) *InstancesSetLabelsCall {
	c := &InstancesSetLabelsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.instancessetlabelsrequest = instancessetlabelsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetLabelsCall) RequestId(requestId string) *InstancesSetLabelsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetLabelsCall) Fields(s ...googleapi.Field) *InstancesSetLabelsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetLabelsCall) Context(ctx context.Context) *InstancesSetLabelsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetLabelsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetLabelsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancessetlabelsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setLabels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setLabels" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetLabelsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets labels on an instance. To learn more about labels, read the Labeling Resources documentation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setLabels",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setLabels",
	//   "request": {
	//     "$ref": "InstancesSetLabelsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setMachineResources":

type InstancesSetMachineResourcesCall struct {
	s                                   *Service
	project                             string
	zone                                string
	instance                            string
	instancessetmachineresourcesrequest *InstancesSetMachineResourcesRequest
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// SetMachineResources: Changes the number and/or type of accelerator
// for a stopped instance to the values specified in the request. (==
// suppress_warning http-rest-shadowed ==)
func (r *InstancesService) SetMachineResources(project string, zone string, instance string, instancessetmachineresourcesrequest *InstancesSetMachineResourcesRequest) *InstancesSetMachineResourcesCall {
	c := &InstancesSetMachineResourcesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.instancessetmachineresourcesrequest = instancessetmachineresourcesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetMachineResourcesCall) RequestId(requestId string) *InstancesSetMachineResourcesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetMachineResourcesCall) Fields(s ...googleapi.Field) *InstancesSetMachineResourcesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetMachineResourcesCall) Context(ctx context.Context) *InstancesSetMachineResourcesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetMachineResourcesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetMachineResourcesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancessetmachineresourcesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setMachineResources")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setMachineResources" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetMachineResourcesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the number and/or type of accelerator for a stopped instance to the values specified in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setMachineResources",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setMachineResources",
	//   "request": {
	//     "$ref": "InstancesSetMachineResourcesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setMachineType":

type InstancesSetMachineTypeCall struct {
	s                              *Service
	project                        string
	zone                           string
	instance                       string
	instancessetmachinetyperequest *InstancesSetMachineTypeRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// SetMachineType: Changes the machine type for a stopped instance to
// the machine type specified in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstancesService) SetMachineType(project string, zone string, instance string, instancessetmachinetyperequest *InstancesSetMachineTypeRequest) *InstancesSetMachineTypeCall {
	c := &InstancesSetMachineTypeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.instancessetmachinetyperequest = instancessetmachinetyperequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetMachineTypeCall) RequestId(requestId string) *InstancesSetMachineTypeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetMachineTypeCall) Fields(s ...googleapi.Field) *InstancesSetMachineTypeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetMachineTypeCall) Context(ctx context.Context) *InstancesSetMachineTypeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetMachineTypeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetMachineTypeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancessetmachinetyperequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setMachineType")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setMachineType" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetMachineTypeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the machine type for a stopped instance to the machine type specified in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setMachineType",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setMachineType",
	//   "request": {
	//     "$ref": "InstancesSetMachineTypeRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setMetadata":

type InstancesSetMetadataCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	metadata   *Metadata
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SetMetadata: Sets metadata for the specified instance to the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/setMetadata
func (r *InstancesService) SetMetadata(project string, zone string, instance string, metadata *Metadata) *InstancesSetMetadataCall {
	c := &InstancesSetMetadataCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.metadata = metadata
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetMetadataCall) RequestId(requestId string) *InstancesSetMetadataCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetMetadataCall) Fields(s ...googleapi.Field) *InstancesSetMetadataCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetMetadataCall) Context(ctx context.Context) *InstancesSetMetadataCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetMetadataCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetMetadataCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.metadata)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setMetadata")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setMetadata" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetMetadataCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets metadata for the specified instance to the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setMetadata",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setMetadata",
	//   "request": {
	//     "$ref": "Metadata"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setMinCpuPlatform":

type InstancesSetMinCpuPlatformCall struct {
	s                                 *Service
	project                           string
	zone                              string
	instance                          string
	instancessetmincpuplatformrequest *InstancesSetMinCpuPlatformRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// SetMinCpuPlatform: Changes the minimum CPU platform that this
// instance should use. This method can only be called on a stopped
// instance. For more information, read Specifying a Minimum CPU
// Platform. (== suppress_warning http-rest-shadowed ==)
func (r *InstancesService) SetMinCpuPlatform(project string, zone string, instance string, instancessetmincpuplatformrequest *InstancesSetMinCpuPlatformRequest) *InstancesSetMinCpuPlatformCall {
	c := &InstancesSetMinCpuPlatformCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.instancessetmincpuplatformrequest = instancessetmincpuplatformrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetMinCpuPlatformCall) RequestId(requestId string) *InstancesSetMinCpuPlatformCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetMinCpuPlatformCall) Fields(s ...googleapi.Field) *InstancesSetMinCpuPlatformCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetMinCpuPlatformCall) Context(ctx context.Context) *InstancesSetMinCpuPlatformCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetMinCpuPlatformCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetMinCpuPlatformCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancessetmincpuplatformrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setMinCpuPlatform")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setMinCpuPlatform" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetMinCpuPlatformCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the minimum CPU platform that this instance should use. This method can only be called on a stopped instance. For more information, read Specifying a Minimum CPU Platform. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setMinCpuPlatform",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setMinCpuPlatform",
	//   "request": {
	//     "$ref": "InstancesSetMinCpuPlatformRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setScheduling":

type InstancesSetSchedulingCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	scheduling *Scheduling
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SetScheduling: Sets an instance's scheduling options. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/setScheduling
func (r *InstancesService) SetScheduling(project string, zone string, instance string, scheduling *Scheduling) *InstancesSetSchedulingCall {
	c := &InstancesSetSchedulingCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.scheduling = scheduling
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetSchedulingCall) RequestId(requestId string) *InstancesSetSchedulingCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetSchedulingCall) Fields(s ...googleapi.Field) *InstancesSetSchedulingCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetSchedulingCall) Context(ctx context.Context) *InstancesSetSchedulingCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetSchedulingCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetSchedulingCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.scheduling)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setScheduling")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setScheduling" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetSchedulingCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets an instance's scheduling options. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setScheduling",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setScheduling",
	//   "request": {
	//     "$ref": "Scheduling"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setServiceAccount":

type InstancesSetServiceAccountCall struct {
	s                                 *Service
	project                           string
	zone                              string
	instance                          string
	instancessetserviceaccountrequest *InstancesSetServiceAccountRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// SetServiceAccount: Sets the service account on the instance. For more
// information, read Changing the service account and access scopes for
// an instance. (== suppress_warning http-rest-shadowed ==)
func (r *InstancesService) SetServiceAccount(project string, zone string, instance string, instancessetserviceaccountrequest *InstancesSetServiceAccountRequest) *InstancesSetServiceAccountCall {
	c := &InstancesSetServiceAccountCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.instancessetserviceaccountrequest = instancessetserviceaccountrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetServiceAccountCall) RequestId(requestId string) *InstancesSetServiceAccountCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetServiceAccountCall) Fields(s ...googleapi.Field) *InstancesSetServiceAccountCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetServiceAccountCall) Context(ctx context.Context) *InstancesSetServiceAccountCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetServiceAccountCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetServiceAccountCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancessetserviceaccountrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setServiceAccount")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setServiceAccount" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetServiceAccountCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the service account on the instance. For more information, read Changing the service account and access scopes for an instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setServiceAccount",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance resource to start.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setServiceAccount",
	//   "request": {
	//     "$ref": "InstancesSetServiceAccountRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setShieldedInstanceIntegrityPolicy":

type InstancesSetShieldedInstanceIntegrityPolicyCall struct {
	s                               *Service
	project                         string
	zone                            string
	instance                        string
	shieldedinstanceintegritypolicy *ShieldedInstanceIntegrityPolicy
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// SetShieldedInstanceIntegrityPolicy: Sets the Shielded Instance
// integrity policy for an instance. You can only use this method on a
// running instance. This method supports PATCH semantics and uses the
// JSON merge patch format and processing rules. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstancesService) SetShieldedInstanceIntegrityPolicy(project string, zone string, instance string, shieldedinstanceintegritypolicy *ShieldedInstanceIntegrityPolicy) *InstancesSetShieldedInstanceIntegrityPolicyCall {
	c := &InstancesSetShieldedInstanceIntegrityPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.shieldedinstanceintegritypolicy = shieldedinstanceintegritypolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetShieldedInstanceIntegrityPolicyCall) RequestId(requestId string) *InstancesSetShieldedInstanceIntegrityPolicyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetShieldedInstanceIntegrityPolicyCall) Fields(s ...googleapi.Field) *InstancesSetShieldedInstanceIntegrityPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetShieldedInstanceIntegrityPolicyCall) Context(ctx context.Context) *InstancesSetShieldedInstanceIntegrityPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetShieldedInstanceIntegrityPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetShieldedInstanceIntegrityPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.shieldedinstanceintegritypolicy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setShieldedInstanceIntegrityPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setShieldedInstanceIntegrityPolicy" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetShieldedInstanceIntegrityPolicyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the Shielded Instance integrity policy for an instance. You can only use this method on a running instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.instances.setShieldedInstanceIntegrityPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name or id of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setShieldedInstanceIntegrityPolicy",
	//   "request": {
	//     "$ref": "ShieldedInstanceIntegrityPolicy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.setTags":

type InstancesSetTagsCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	tags       *Tags
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SetTags: Sets network tags for the specified instance to the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/setTags
func (r *InstancesService) SetTags(project string, zone string, instance string, tags *Tags) *InstancesSetTagsCall {
	c := &InstancesSetTagsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.tags = tags
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesSetTagsCall) RequestId(requestId string) *InstancesSetTagsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSetTagsCall) Fields(s ...googleapi.Field) *InstancesSetTagsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSetTagsCall) Context(ctx context.Context) *InstancesSetTagsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSetTagsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSetTagsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.tags)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setTags")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.setTags" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSetTagsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets network tags for the specified instance to the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.setTags",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/setTags",
	//   "request": {
	//     "$ref": "Tags"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.simulateMaintenanceEvent":

type InstancesSimulateMaintenanceEventCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SimulateMaintenanceEvent: Simulates a maintenance event on the
// instance. (== suppress_warning http-rest-shadowed ==)
func (r *InstancesService) SimulateMaintenanceEvent(project string, zone string, instance string) *InstancesSimulateMaintenanceEventCall {
	c := &InstancesSimulateMaintenanceEventCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesSimulateMaintenanceEventCall) Fields(s ...googleapi.Field) *InstancesSimulateMaintenanceEventCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesSimulateMaintenanceEventCall) Context(ctx context.Context) *InstancesSimulateMaintenanceEventCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesSimulateMaintenanceEventCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesSimulateMaintenanceEventCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/simulateMaintenanceEvent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.simulateMaintenanceEvent" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesSimulateMaintenanceEventCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Simulates a maintenance event on the instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.simulateMaintenanceEvent",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/simulateMaintenanceEvent",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.start":

type InstancesStartCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Start: Starts an instance that was stopped using the instances().stop
// method. For more information, see Restart an instance. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/start
func (r *InstancesService) Start(project string, zone string, instance string) *InstancesStartCall {
	c := &InstancesStartCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesStartCall) RequestId(requestId string) *InstancesStartCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesStartCall) Fields(s ...googleapi.Field) *InstancesStartCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesStartCall) Context(ctx context.Context) *InstancesStartCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesStartCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesStartCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/start")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.start" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesStartCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Starts an instance that was stopped using the instances().stop method. For more information, see Restart an instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.start",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance resource to start.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/start",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.startWithEncryptionKey":

type InstancesStartWithEncryptionKeyCall struct {
	s                                      *Service
	project                                string
	zone                                   string
	instance                               string
	instancesstartwithencryptionkeyrequest *InstancesStartWithEncryptionKeyRequest
	urlParams_                             gensupport.URLParams
	ctx_                                   context.Context
	header_                                http.Header
}

// StartWithEncryptionKey: Starts an instance that was stopped using the
// instances().stop method. For more information, see Restart an
// instance. (== suppress_warning http-rest-shadowed ==)
func (r *InstancesService) StartWithEncryptionKey(project string, zone string, instance string, instancesstartwithencryptionkeyrequest *InstancesStartWithEncryptionKeyRequest) *InstancesStartWithEncryptionKeyCall {
	c := &InstancesStartWithEncryptionKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.instancesstartwithencryptionkeyrequest = instancesstartwithencryptionkeyrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesStartWithEncryptionKeyCall) RequestId(requestId string) *InstancesStartWithEncryptionKeyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesStartWithEncryptionKeyCall) Fields(s ...googleapi.Field) *InstancesStartWithEncryptionKeyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesStartWithEncryptionKeyCall) Context(ctx context.Context) *InstancesStartWithEncryptionKeyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesStartWithEncryptionKeyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesStartWithEncryptionKeyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancesstartwithencryptionkeyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/startWithEncryptionKey")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.startWithEncryptionKey" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesStartWithEncryptionKeyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Starts an instance that was stopped using the instances().stop method. For more information, see Restart an instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.startWithEncryptionKey",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance resource to start.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/startWithEncryptionKey",
	//   "request": {
	//     "$ref": "InstancesStartWithEncryptionKeyRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.stop":

type InstancesStopCall struct {
	s          *Service
	project    string
	zone       string
	instance   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Stop: Stops a running instance, shutting it down cleanly, and allows
// you to restart the instance at a later time. Stopped instances do not
// incur VM usage charges while they are stopped. However, resources
// that the VM is using, such as persistent disks and static IP
// addresses, will continue to be charged until they are deleted. For
// more information, see Stopping an instance. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/instances/stop
func (r *InstancesService) Stop(project string, zone string, instance string) *InstancesStopCall {
	c := &InstancesStopCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesStopCall) RequestId(requestId string) *InstancesStopCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesStopCall) Fields(s ...googleapi.Field) *InstancesStopCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesStopCall) Context(ctx context.Context) *InstancesStopCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesStopCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesStopCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/stop")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.stop" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesStopCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Stops a running instance, shutting it down cleanly, and allows you to restart the instance at a later time. Stopped instances do not incur VM usage charges while they are stopped. However, resources that the VM is using, such as persistent disks and static IP addresses, will continue to be charged until they are deleted. For more information, see Stopping an instance. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.stop",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance resource to stop.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/stop",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.testIamPermissions":

type InstancesTestIamPermissionsCall struct {
	s                      *Service
	project                string
	zone                   string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *InstancesService) TestIamPermissions(project string, zone string, resource string, testpermissionsrequest *TestPermissionsRequest) *InstancesTestIamPermissionsCall {
	c := &InstancesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesTestIamPermissionsCall) Fields(s ...googleapi.Field) *InstancesTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesTestIamPermissionsCall) Context(ctx context.Context) *InstancesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InstancesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.instances.updateAccessConfig":

type InstancesUpdateAccessConfigCall struct {
	s            *Service
	project      string
	zone         string
	instance     string
	accessconfig *AccessConfig
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// UpdateAccessConfig: Updates the specified access config from an
// instance's network interface with the data included in the request.
// This method supports PATCH semantics and uses the JSON merge patch
// format and processing rules. (== suppress_warning http-rest-shadowed
// ==)
func (r *InstancesService) UpdateAccessConfig(project string, zone string, instance string, networkInterface string, accessconfig *AccessConfig) *InstancesUpdateAccessConfigCall {
	c := &InstancesUpdateAccessConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.urlParams_.Set("networkInterface", networkInterface)
	c.accessconfig = accessconfig
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesUpdateAccessConfigCall) RequestId(requestId string) *InstancesUpdateAccessConfigCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesUpdateAccessConfigCall) Fields(s ...googleapi.Field) *InstancesUpdateAccessConfigCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesUpdateAccessConfigCall) Context(ctx context.Context) *InstancesUpdateAccessConfigCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesUpdateAccessConfigCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesUpdateAccessConfigCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.accessconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/updateAccessConfig")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.updateAccessConfig" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesUpdateAccessConfigCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified access config from an instance's network interface with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.instances.updateAccessConfig",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance",
	//     "networkInterface"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "The instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "networkInterface": {
	//       "description": "The name of the network interface where the access config is attached.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/updateAccessConfig",
	//   "request": {
	//     "$ref": "AccessConfig"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.updateDisplayDevice":

type InstancesUpdateDisplayDeviceCall struct {
	s             *Service
	project       string
	zone          string
	instance      string
	displaydevice *DisplayDevice
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// UpdateDisplayDevice: Updates the Display config for a VM instance.
// You can only use this method on a stopped VM instance. This method
// supports PATCH semantics and uses the JSON merge patch format and
// processing rules. (== suppress_warning http-rest-shadowed ==)
func (r *InstancesService) UpdateDisplayDevice(project string, zone string, instance string, displaydevice *DisplayDevice) *InstancesUpdateDisplayDeviceCall {
	c := &InstancesUpdateDisplayDeviceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.displaydevice = displaydevice
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesUpdateDisplayDeviceCall) RequestId(requestId string) *InstancesUpdateDisplayDeviceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesUpdateDisplayDeviceCall) Fields(s ...googleapi.Field) *InstancesUpdateDisplayDeviceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesUpdateDisplayDeviceCall) Context(ctx context.Context) *InstancesUpdateDisplayDeviceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesUpdateDisplayDeviceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesUpdateDisplayDeviceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.displaydevice)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/updateDisplayDevice")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.updateDisplayDevice" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesUpdateDisplayDeviceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the Display config for a VM instance. You can only use this method on a stopped VM instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.instances.updateDisplayDevice",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/updateDisplayDevice",
	//   "request": {
	//     "$ref": "DisplayDevice"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.updateNetworkInterface":

type InstancesUpdateNetworkInterfaceCall struct {
	s                *Service
	project          string
	zone             string
	instance         string
	networkinterface *NetworkInterface
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// UpdateNetworkInterface: Updates an instance's network interface. This
// method follows PATCH semantics. (== suppress_warning
// http-rest-shadowed ==)
func (r *InstancesService) UpdateNetworkInterface(project string, zone string, instance string, networkInterface string, networkinterface *NetworkInterface) *InstancesUpdateNetworkInterfaceCall {
	c := &InstancesUpdateNetworkInterfaceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.urlParams_.Set("networkInterface", networkInterface)
	c.networkinterface = networkinterface
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesUpdateNetworkInterfaceCall) RequestId(requestId string) *InstancesUpdateNetworkInterfaceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesUpdateNetworkInterfaceCall) Fields(s ...googleapi.Field) *InstancesUpdateNetworkInterfaceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesUpdateNetworkInterfaceCall) Context(ctx context.Context) *InstancesUpdateNetworkInterfaceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesUpdateNetworkInterfaceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesUpdateNetworkInterfaceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networkinterface)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/updateNetworkInterface")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.updateNetworkInterface" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesUpdateNetworkInterfaceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an instance's network interface. This method follows PATCH semantics. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.instances.updateNetworkInterface",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance",
	//     "networkInterface"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "The instance name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "networkInterface": {
	//       "description": "The name of the network interface to update.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/updateNetworkInterface",
	//   "request": {
	//     "$ref": "NetworkInterface"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.instances.updateShieldedInstanceConfig":

type InstancesUpdateShieldedInstanceConfigCall struct {
	s                      *Service
	project                string
	zone                   string
	instance               string
	shieldedinstanceconfig *ShieldedInstanceConfig
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// UpdateShieldedInstanceConfig: Updates the Shielded Instance config
// for an instance. You can only use this method on a stopped instance.
// This method supports PATCH semantics and uses the JSON merge patch
// format and processing rules. (== suppress_warning http-rest-shadowed
// ==)
func (r *InstancesService) UpdateShieldedInstanceConfig(project string, zone string, instance string, shieldedinstanceconfig *ShieldedInstanceConfig) *InstancesUpdateShieldedInstanceConfigCall {
	c := &InstancesUpdateShieldedInstanceConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.instance = instance
	c.shieldedinstanceconfig = shieldedinstanceconfig
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InstancesUpdateShieldedInstanceConfigCall) RequestId(requestId string) *InstancesUpdateShieldedInstanceConfigCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InstancesUpdateShieldedInstanceConfigCall) Fields(s ...googleapi.Field) *InstancesUpdateShieldedInstanceConfigCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InstancesUpdateShieldedInstanceConfigCall) Context(ctx context.Context) *InstancesUpdateShieldedInstanceConfigCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InstancesUpdateShieldedInstanceConfigCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InstancesUpdateShieldedInstanceConfigCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.shieldedinstanceconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/updateShieldedInstanceConfig")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.instances.updateShieldedInstanceConfig" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InstancesUpdateShieldedInstanceConfigCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the Shielded Instance config for an instance. You can only use this method on a stopped instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.instances.updateShieldedInstanceConfig",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Name or id of the instance scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/instances/{instance}/updateShieldedInstanceConfig",
	//   "request": {
	//     "$ref": "ShieldedInstanceConfig"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.interconnectAttachments.aggregatedList":

type InterconnectAttachmentsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of interconnect
// attachments. (== suppress_warning http-rest-shadowed ==)
func (r *InterconnectAttachmentsService) AggregatedList(project string) *InterconnectAttachmentsAggregatedListCall {
	c := &InterconnectAttachmentsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InterconnectAttachmentsAggregatedListCall) Filter(filter string) *InterconnectAttachmentsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InterconnectAttachmentsAggregatedListCall) MaxResults(maxResults int64) *InterconnectAttachmentsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InterconnectAttachmentsAggregatedListCall) OrderBy(orderBy string) *InterconnectAttachmentsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InterconnectAttachmentsAggregatedListCall) PageToken(pageToken string) *InterconnectAttachmentsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectAttachmentsAggregatedListCall) Fields(s ...googleapi.Field) *InterconnectAttachmentsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectAttachmentsAggregatedListCall) IfNoneMatch(entityTag string) *InterconnectAttachmentsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectAttachmentsAggregatedListCall) Context(ctx context.Context) *InterconnectAttachmentsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectAttachmentsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectAttachmentsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/interconnectAttachments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectAttachments.aggregatedList" call.
// Exactly one of *InterconnectAttachmentAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *InterconnectAttachmentAggregatedList.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *InterconnectAttachmentsAggregatedListCall) Do(opts ...googleapi.CallOption) (*InterconnectAttachmentAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InterconnectAttachmentAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of interconnect attachments. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnectAttachments.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/interconnectAttachments",
	//   "response": {
	//     "$ref": "InterconnectAttachmentAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InterconnectAttachmentsAggregatedListCall) Pages(ctx context.Context, f func(*InterconnectAttachmentAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.interconnectAttachments.delete":

type InterconnectAttachmentsDeleteCall struct {
	s                      *Service
	project                string
	region                 string
	interconnectAttachment string
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Delete: Deletes the specified interconnect attachment. (==
// suppress_warning http-rest-shadowed ==)
func (r *InterconnectAttachmentsService) Delete(project string, region string, interconnectAttachment string) *InterconnectAttachmentsDeleteCall {
	c := &InterconnectAttachmentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.interconnectAttachment = interconnectAttachment
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InterconnectAttachmentsDeleteCall) RequestId(requestId string) *InterconnectAttachmentsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectAttachmentsDeleteCall) Fields(s ...googleapi.Field) *InterconnectAttachmentsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectAttachmentsDeleteCall) Context(ctx context.Context) *InterconnectAttachmentsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectAttachmentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectAttachmentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/interconnectAttachments/{interconnectAttachment}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":                c.project,
		"region":                 c.region,
		"interconnectAttachment": c.interconnectAttachment,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectAttachments.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InterconnectAttachmentsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified interconnect attachment. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.interconnectAttachments.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "interconnectAttachment"
	//   ],
	//   "parameters": {
	//     "interconnectAttachment": {
	//       "description": "Name of the interconnect attachment to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/interconnectAttachments/{interconnectAttachment}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.interconnectAttachments.get":

type InterconnectAttachmentsGetCall struct {
	s                      *Service
	project                string
	region                 string
	interconnectAttachment string
	urlParams_             gensupport.URLParams
	ifNoneMatch_           string
	ctx_                   context.Context
	header_                http.Header
}

// Get: Returns the specified interconnect attachment. (==
// suppress_warning http-rest-shadowed ==)
func (r *InterconnectAttachmentsService) Get(project string, region string, interconnectAttachment string) *InterconnectAttachmentsGetCall {
	c := &InterconnectAttachmentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.interconnectAttachment = interconnectAttachment
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectAttachmentsGetCall) Fields(s ...googleapi.Field) *InterconnectAttachmentsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectAttachmentsGetCall) IfNoneMatch(entityTag string) *InterconnectAttachmentsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectAttachmentsGetCall) Context(ctx context.Context) *InterconnectAttachmentsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectAttachmentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectAttachmentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/interconnectAttachments/{interconnectAttachment}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":                c.project,
		"region":                 c.region,
		"interconnectAttachment": c.interconnectAttachment,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectAttachments.get" call.
// Exactly one of *InterconnectAttachment or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InterconnectAttachment.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InterconnectAttachmentsGetCall) Do(opts ...googleapi.CallOption) (*InterconnectAttachment, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InterconnectAttachment{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified interconnect attachment. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnectAttachments.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "interconnectAttachment"
	//   ],
	//   "parameters": {
	//     "interconnectAttachment": {
	//       "description": "Name of the interconnect attachment to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/interconnectAttachments/{interconnectAttachment}",
	//   "response": {
	//     "$ref": "InterconnectAttachment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.interconnectAttachments.insert":

type InterconnectAttachmentsInsertCall struct {
	s                      *Service
	project                string
	region                 string
	interconnectattachment *InterconnectAttachment
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Insert: Creates an InterconnectAttachment in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *InterconnectAttachmentsService) Insert(project string, region string, interconnectattachment *InterconnectAttachment) *InterconnectAttachmentsInsertCall {
	c := &InterconnectAttachmentsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.interconnectattachment = interconnectattachment
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InterconnectAttachmentsInsertCall) RequestId(requestId string) *InterconnectAttachmentsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectAttachmentsInsertCall) Fields(s ...googleapi.Field) *InterconnectAttachmentsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectAttachmentsInsertCall) Context(ctx context.Context) *InterconnectAttachmentsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectAttachmentsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectAttachmentsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.interconnectattachment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/interconnectAttachments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectAttachments.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InterconnectAttachmentsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an InterconnectAttachment in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.interconnectAttachments.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/interconnectAttachments",
	//   "request": {
	//     "$ref": "InterconnectAttachment"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.interconnectAttachments.list":

type InterconnectAttachmentsListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of interconnect attachments contained within
// the specified region. (== suppress_warning http-rest-shadowed ==)
func (r *InterconnectAttachmentsService) List(project string, region string) *InterconnectAttachmentsListCall {
	c := &InterconnectAttachmentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InterconnectAttachmentsListCall) Filter(filter string) *InterconnectAttachmentsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InterconnectAttachmentsListCall) MaxResults(maxResults int64) *InterconnectAttachmentsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InterconnectAttachmentsListCall) OrderBy(orderBy string) *InterconnectAttachmentsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InterconnectAttachmentsListCall) PageToken(pageToken string) *InterconnectAttachmentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectAttachmentsListCall) Fields(s ...googleapi.Field) *InterconnectAttachmentsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectAttachmentsListCall) IfNoneMatch(entityTag string) *InterconnectAttachmentsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectAttachmentsListCall) Context(ctx context.Context) *InterconnectAttachmentsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectAttachmentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectAttachmentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/interconnectAttachments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectAttachments.list" call.
// Exactly one of *InterconnectAttachmentList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *InterconnectAttachmentList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InterconnectAttachmentsListCall) Do(opts ...googleapi.CallOption) (*InterconnectAttachmentList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InterconnectAttachmentList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of interconnect attachments contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnectAttachments.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/interconnectAttachments",
	//   "response": {
	//     "$ref": "InterconnectAttachmentList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InterconnectAttachmentsListCall) Pages(ctx context.Context, f func(*InterconnectAttachmentList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.interconnectAttachments.patch":

type InterconnectAttachmentsPatchCall struct {
	s                      *Service
	project                string
	region                 string
	interconnectAttachment string
	interconnectattachment *InterconnectAttachment
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Patch: Updates the specified interconnect attachment with the data
// included in the request. This method supports PATCH semantics and
// uses the JSON merge patch format and processing rules. (==
// suppress_warning http-rest-shadowed ==)
func (r *InterconnectAttachmentsService) Patch(project string, region string, interconnectAttachment string, interconnectattachment *InterconnectAttachment) *InterconnectAttachmentsPatchCall {
	c := &InterconnectAttachmentsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.interconnectAttachment = interconnectAttachment
	c.interconnectattachment = interconnectattachment
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InterconnectAttachmentsPatchCall) RequestId(requestId string) *InterconnectAttachmentsPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectAttachmentsPatchCall) Fields(s ...googleapi.Field) *InterconnectAttachmentsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectAttachmentsPatchCall) Context(ctx context.Context) *InterconnectAttachmentsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectAttachmentsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectAttachmentsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.interconnectattachment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/interconnectAttachments/{interconnectAttachment}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":                c.project,
		"region":                 c.region,
		"interconnectAttachment": c.interconnectAttachment,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectAttachments.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InterconnectAttachmentsPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified interconnect attachment with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.interconnectAttachments.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "interconnectAttachment"
	//   ],
	//   "parameters": {
	//     "interconnectAttachment": {
	//       "description": "Name of the interconnect attachment to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/interconnectAttachments/{interconnectAttachment}",
	//   "request": {
	//     "$ref": "InterconnectAttachment"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.interconnectLocations.get":

type InterconnectLocationsGetCall struct {
	s                    *Service
	project              string
	interconnectLocation string
	urlParams_           gensupport.URLParams
	ifNoneMatch_         string
	ctx_                 context.Context
	header_              http.Header
}

// Get: Returns the details for the specified interconnect location.
// Gets a list of available interconnect locations by making a list()
// request. (== suppress_warning http-rest-shadowed ==)
func (r *InterconnectLocationsService) Get(project string, interconnectLocation string) *InterconnectLocationsGetCall {
	c := &InterconnectLocationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.interconnectLocation = interconnectLocation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectLocationsGetCall) Fields(s ...googleapi.Field) *InterconnectLocationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectLocationsGetCall) IfNoneMatch(entityTag string) *InterconnectLocationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectLocationsGetCall) Context(ctx context.Context) *InterconnectLocationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectLocationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectLocationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnectLocations/{interconnectLocation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"interconnectLocation": c.interconnectLocation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectLocations.get" call.
// Exactly one of *InterconnectLocation or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InterconnectLocation.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InterconnectLocationsGetCall) Do(opts ...googleapi.CallOption) (*InterconnectLocation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InterconnectLocation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the details for the specified interconnect location. Gets a list of available interconnect locations by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnectLocations.get",
	//   "parameterOrder": [
	//     "project",
	//     "interconnectLocation"
	//   ],
	//   "parameters": {
	//     "interconnectLocation": {
	//       "description": "Name of the interconnect location to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnectLocations/{interconnectLocation}",
	//   "response": {
	//     "$ref": "InterconnectLocation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.interconnectLocations.list":

type InterconnectLocationsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of interconnect locations available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *InterconnectLocationsService) List(project string) *InterconnectLocationsListCall {
	c := &InterconnectLocationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InterconnectLocationsListCall) Filter(filter string) *InterconnectLocationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InterconnectLocationsListCall) MaxResults(maxResults int64) *InterconnectLocationsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InterconnectLocationsListCall) OrderBy(orderBy string) *InterconnectLocationsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InterconnectLocationsListCall) PageToken(pageToken string) *InterconnectLocationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectLocationsListCall) Fields(s ...googleapi.Field) *InterconnectLocationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectLocationsListCall) IfNoneMatch(entityTag string) *InterconnectLocationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectLocationsListCall) Context(ctx context.Context) *InterconnectLocationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectLocationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectLocationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnectLocations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnectLocations.list" call.
// Exactly one of *InterconnectLocationList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *InterconnectLocationList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InterconnectLocationsListCall) Do(opts ...googleapi.CallOption) (*InterconnectLocationList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InterconnectLocationList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of interconnect locations available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnectLocations.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnectLocations",
	//   "response": {
	//     "$ref": "InterconnectLocationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InterconnectLocationsListCall) Pages(ctx context.Context, f func(*InterconnectLocationList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.interconnects.delete":

type InterconnectsDeleteCall struct {
	s            *Service
	project      string
	interconnect string
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Deletes the specified interconnect. (== suppress_warning
// http-rest-shadowed ==)
func (r *InterconnectsService) Delete(project string, interconnect string) *InterconnectsDeleteCall {
	c := &InterconnectsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.interconnect = interconnect
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InterconnectsDeleteCall) RequestId(requestId string) *InterconnectsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectsDeleteCall) Fields(s ...googleapi.Field) *InterconnectsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectsDeleteCall) Context(ctx context.Context) *InterconnectsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnects/{interconnect}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":      c.project,
		"interconnect": c.interconnect,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnects.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InterconnectsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified interconnect. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.interconnects.delete",
	//   "parameterOrder": [
	//     "project",
	//     "interconnect"
	//   ],
	//   "parameters": {
	//     "interconnect": {
	//       "description": "Name of the interconnect to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnects/{interconnect}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.interconnects.get":

type InterconnectsGetCall struct {
	s            *Service
	project      string
	interconnect string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified interconnect. Get a list of available
// interconnects by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *InterconnectsService) Get(project string, interconnect string) *InterconnectsGetCall {
	c := &InterconnectsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.interconnect = interconnect
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectsGetCall) Fields(s ...googleapi.Field) *InterconnectsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectsGetCall) IfNoneMatch(entityTag string) *InterconnectsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectsGetCall) Context(ctx context.Context) *InterconnectsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnects/{interconnect}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":      c.project,
		"interconnect": c.interconnect,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnects.get" call.
// Exactly one of *Interconnect or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Interconnect.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InterconnectsGetCall) Do(opts ...googleapi.CallOption) (*Interconnect, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Interconnect{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified interconnect. Get a list of available interconnects by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnects.get",
	//   "parameterOrder": [
	//     "project",
	//     "interconnect"
	//   ],
	//   "parameters": {
	//     "interconnect": {
	//       "description": "Name of the interconnect to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnects/{interconnect}",
	//   "response": {
	//     "$ref": "Interconnect"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.interconnects.getDiagnostics":

type InterconnectsGetDiagnosticsCall struct {
	s            *Service
	project      string
	interconnect string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetDiagnostics: Returns the interconnectDiagnostics for the specified
// interconnect. (== suppress_warning http-rest-shadowed ==)
func (r *InterconnectsService) GetDiagnostics(project string, interconnect string) *InterconnectsGetDiagnosticsCall {
	c := &InterconnectsGetDiagnosticsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.interconnect = interconnect
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectsGetDiagnosticsCall) Fields(s ...googleapi.Field) *InterconnectsGetDiagnosticsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectsGetDiagnosticsCall) IfNoneMatch(entityTag string) *InterconnectsGetDiagnosticsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectsGetDiagnosticsCall) Context(ctx context.Context) *InterconnectsGetDiagnosticsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectsGetDiagnosticsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectsGetDiagnosticsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnects/{interconnect}/getDiagnostics")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":      c.project,
		"interconnect": c.interconnect,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnects.getDiagnostics" call.
// Exactly one of *InterconnectsGetDiagnosticsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *InterconnectsGetDiagnosticsResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *InterconnectsGetDiagnosticsCall) Do(opts ...googleapi.CallOption) (*InterconnectsGetDiagnosticsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InterconnectsGetDiagnosticsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the interconnectDiagnostics for the specified interconnect. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnects.getDiagnostics",
	//   "parameterOrder": [
	//     "project",
	//     "interconnect"
	//   ],
	//   "parameters": {
	//     "interconnect": {
	//       "description": "Name of the interconnect resource to query.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnects/{interconnect}/getDiagnostics",
	//   "response": {
	//     "$ref": "InterconnectsGetDiagnosticsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.interconnects.insert":

type InterconnectsInsertCall struct {
	s            *Service
	project      string
	interconnect *Interconnect
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Insert: Creates a Interconnect in the specified project using the
// data included in the request. (== suppress_warning http-rest-shadowed
// ==)
func (r *InterconnectsService) Insert(project string, interconnect *Interconnect) *InterconnectsInsertCall {
	c := &InterconnectsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.interconnect = interconnect
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InterconnectsInsertCall) RequestId(requestId string) *InterconnectsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectsInsertCall) Fields(s ...googleapi.Field) *InterconnectsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectsInsertCall) Context(ctx context.Context) *InterconnectsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.interconnect)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnects")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnects.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InterconnectsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a Interconnect in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.interconnects.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnects",
	//   "request": {
	//     "$ref": "Interconnect"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.interconnects.list":

type InterconnectsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of interconnect available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
func (r *InterconnectsService) List(project string) *InterconnectsListCall {
	c := &InterconnectsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *InterconnectsListCall) Filter(filter string) *InterconnectsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *InterconnectsListCall) MaxResults(maxResults int64) *InterconnectsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *InterconnectsListCall) OrderBy(orderBy string) *InterconnectsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *InterconnectsListCall) PageToken(pageToken string) *InterconnectsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectsListCall) Fields(s ...googleapi.Field) *InterconnectsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *InterconnectsListCall) IfNoneMatch(entityTag string) *InterconnectsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectsListCall) Context(ctx context.Context) *InterconnectsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnects")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnects.list" call.
// Exactly one of *InterconnectList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InterconnectList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InterconnectsListCall) Do(opts ...googleapi.CallOption) (*InterconnectList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InterconnectList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of interconnect available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.interconnects.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnects",
	//   "response": {
	//     "$ref": "InterconnectList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *InterconnectsListCall) Pages(ctx context.Context, f func(*InterconnectList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.interconnects.patch":

type InterconnectsPatchCall struct {
	s             *Service
	project       string
	interconnect  string
	interconnect2 *Interconnect
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Patch: Updates the specified interconnect with the data included in
// the request. This method supports PATCH semantics and uses the JSON
// merge patch format and processing rules. (== suppress_warning
// http-rest-shadowed ==)
func (r *InterconnectsService) Patch(project string, interconnect string, interconnect2 *Interconnect) *InterconnectsPatchCall {
	c := &InterconnectsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.interconnect = interconnect
	c.interconnect2 = interconnect2
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *InterconnectsPatchCall) RequestId(requestId string) *InterconnectsPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InterconnectsPatchCall) Fields(s ...googleapi.Field) *InterconnectsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *InterconnectsPatchCall) Context(ctx context.Context) *InterconnectsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InterconnectsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InterconnectsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.interconnect2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/interconnects/{interconnect}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":      c.project,
		"interconnect": c.interconnect,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.interconnects.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *InterconnectsPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified interconnect with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.interconnects.patch",
	//   "parameterOrder": [
	//     "project",
	//     "interconnect"
	//   ],
	//   "parameters": {
	//     "interconnect": {
	//       "description": "Name of the interconnect to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/interconnects/{interconnect}",
	//   "request": {
	//     "$ref": "Interconnect"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.licenseCodes.get":

type LicenseCodesGetCall struct {
	s            *Service
	project      string
	licenseCode  string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Return a specified license code. License codes are mirrored
// across all projects that have permissions to read the License Code.
// (== suppress_warning http-rest-shadowed ==)
func (r *LicenseCodesService) Get(project string, licenseCode string) *LicenseCodesGetCall {
	c := &LicenseCodesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.licenseCode = licenseCode
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicenseCodesGetCall) Fields(s ...googleapi.Field) *LicenseCodesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *LicenseCodesGetCall) IfNoneMatch(entityTag string) *LicenseCodesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicenseCodesGetCall) Context(ctx context.Context) *LicenseCodesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicenseCodesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseCodesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenseCodes/{licenseCode}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"licenseCode": c.licenseCode,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenseCodes.get" call.
// Exactly one of *LicenseCode or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LicenseCode.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *LicenseCodesGetCall) Do(opts ...googleapi.CallOption) (*LicenseCode, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicenseCode{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Return a specified license code. License codes are mirrored across all projects that have permissions to read the License Code. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.licenseCodes.get",
	//   "parameterOrder": [
	//     "project",
	//     "licenseCode"
	//   ],
	//   "parameters": {
	//     "licenseCode": {
	//       "description": "Number corresponding to the License code resource to return.",
	//       "location": "path",
	//       "pattern": "[0-9]{0,61}?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenseCodes/{licenseCode}",
	//   "response": {
	//     "$ref": "LicenseCode"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.licenseCodes.testIamPermissions":

type LicenseCodesTestIamPermissionsCall struct {
	s                      *Service
	project                string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *LicenseCodesService) TestIamPermissions(project string, resource string, testpermissionsrequest *TestPermissionsRequest) *LicenseCodesTestIamPermissionsCall {
	c := &LicenseCodesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicenseCodesTestIamPermissionsCall) Fields(s ...googleapi.Field) *LicenseCodesTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicenseCodesTestIamPermissionsCall) Context(ctx context.Context) *LicenseCodesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicenseCodesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseCodesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenseCodes/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenseCodes.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicenseCodesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.licenseCodes.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenseCodes/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.licenses.delete":

type LicensesDeleteCall struct {
	s          *Service
	project    string
	license    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified license. (== suppress_warning
// http-rest-shadowed ==)
func (r *LicensesService) Delete(project string, license string) *LicensesDeleteCall {
	c := &LicensesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.license = license
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *LicensesDeleteCall) RequestId(requestId string) *LicensesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicensesDeleteCall) Fields(s ...googleapi.Field) *LicensesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicensesDeleteCall) Context(ctx context.Context) *LicensesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicensesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicensesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses/{license}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"license": c.license,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenses.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *LicensesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified license. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.licenses.delete",
	//   "parameterOrder": [
	//     "project",
	//     "license"
	//   ],
	//   "parameters": {
	//     "license": {
	//       "description": "Name of the license resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenses/{license}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.licenses.get":

type LicensesGetCall struct {
	s            *Service
	project      string
	license      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified License resource. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/licenses/get
func (r *LicensesService) Get(project string, license string) *LicensesGetCall {
	c := &LicensesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.license = license
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicensesGetCall) Fields(s ...googleapi.Field) *LicensesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *LicensesGetCall) IfNoneMatch(entityTag string) *LicensesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicensesGetCall) Context(ctx context.Context) *LicensesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicensesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicensesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses/{license}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"license": c.license,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenses.get" call.
// Exactly one of *License or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *License.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *LicensesGetCall) Do(opts ...googleapi.CallOption) (*License, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &License{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified License resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.licenses.get",
	//   "parameterOrder": [
	//     "project",
	//     "license"
	//   ],
	//   "parameters": {
	//     "license": {
	//       "description": "Name of the License resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenses/{license}",
	//   "response": {
	//     "$ref": "License"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.licenses.getIamPolicy":

type LicensesGetIamPolicyCall struct {
	s            *Service
	project      string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *LicensesService) GetIamPolicy(project string, resource string) *LicensesGetIamPolicyCall {
	c := &LicensesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicensesGetIamPolicyCall) Fields(s ...googleapi.Field) *LicensesGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *LicensesGetIamPolicyCall) IfNoneMatch(entityTag string) *LicensesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicensesGetIamPolicyCall) Context(ctx context.Context) *LicensesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicensesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicensesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenses.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *LicensesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.licenses.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenses/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.licenses.insert":

type LicensesInsertCall struct {
	s          *Service
	project    string
	license    *License
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Create a License resource in the specified project. (==
// suppress_warning http-rest-shadowed ==)
func (r *LicensesService) Insert(project string, license *License) *LicensesInsertCall {
	c := &LicensesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.license = license
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *LicensesInsertCall) RequestId(requestId string) *LicensesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicensesInsertCall) Fields(s ...googleapi.Field) *LicensesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicensesInsertCall) Context(ctx context.Context) *LicensesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicensesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicensesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.license)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenses.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *LicensesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Create a License resource in the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.licenses.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenses",
	//   "request": {
	//     "$ref": "License"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/devstorage.full_control",
	//     "https://www.googleapis.com/auth/devstorage.read_only",
	//     "https://www.googleapis.com/auth/devstorage.read_write"
	//   ]
	// }

}

// method id "compute.licenses.list":

type LicensesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of licenses available in the specified
// project. This method does not get any licenses that belong to other
// projects, including licenses attached to publicly-available images,
// like Debian 9. If you want to get a list of publicly-available
// licenses, use this method to make a request to the respective image
// project, such as debian-cloud or windows-cloud. (== suppress_warning
// http-rest-shadowed ==)
func (r *LicensesService) List(project string) *LicensesListCall {
	c := &LicensesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *LicensesListCall) Filter(filter string) *LicensesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *LicensesListCall) MaxResults(maxResults int64) *LicensesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *LicensesListCall) OrderBy(orderBy string) *LicensesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *LicensesListCall) PageToken(pageToken string) *LicensesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicensesListCall) Fields(s ...googleapi.Field) *LicensesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *LicensesListCall) IfNoneMatch(entityTag string) *LicensesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicensesListCall) Context(ctx context.Context) *LicensesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicensesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicensesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenses.list" call.
// Exactly one of *LicensesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LicensesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicensesListCall) Do(opts ...googleapi.CallOption) (*LicensesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicensesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of licenses available in the specified project. This method does not get any licenses that belong to other projects, including licenses attached to publicly-available images, like Debian 9. If you want to get a list of publicly-available licenses, use this method to make a request to the respective image project, such as debian-cloud or windows-cloud. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.licenses.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenses",
	//   "response": {
	//     "$ref": "LicensesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *LicensesListCall) Pages(ctx context.Context, f func(*LicensesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.licenses.setIamPolicy":

type LicensesSetIamPolicyCall struct {
	s                      *Service
	project                string
	resource               string
	globalsetpolicyrequest *GlobalSetPolicyRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *LicensesService) SetIamPolicy(project string, resource string, globalsetpolicyrequest *GlobalSetPolicyRequest) *LicensesSetIamPolicyCall {
	c := &LicensesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.globalsetpolicyrequest = globalsetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicensesSetIamPolicyCall) Fields(s ...googleapi.Field) *LicensesSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicensesSetIamPolicyCall) Context(ctx context.Context) *LicensesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicensesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicensesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.globalsetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenses.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *LicensesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.licenses.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenses/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "GlobalSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.licenses.testIamPermissions":

type LicensesTestIamPermissionsCall struct {
	s                      *Service
	project                string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *LicensesService) TestIamPermissions(project string, resource string, testpermissionsrequest *TestPermissionsRequest) *LicensesTestIamPermissionsCall {
	c := &LicensesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicensesTestIamPermissionsCall) Fields(s ...googleapi.Field) *LicensesTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LicensesTestIamPermissionsCall) Context(ctx context.Context) *LicensesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LicensesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicensesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.licenses.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicensesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.licenses.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/licenses/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.machineTypes.aggregatedList":

type MachineTypesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of machine types. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/machineTypes/aggregatedList
func (r *MachineTypesService) AggregatedList(project string) *MachineTypesAggregatedListCall {
	c := &MachineTypesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *MachineTypesAggregatedListCall) Filter(filter string) *MachineTypesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *MachineTypesAggregatedListCall) MaxResults(maxResults int64) *MachineTypesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *MachineTypesAggregatedListCall) OrderBy(orderBy string) *MachineTypesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *MachineTypesAggregatedListCall) PageToken(pageToken string) *MachineTypesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MachineTypesAggregatedListCall) Fields(s ...googleapi.Field) *MachineTypesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *MachineTypesAggregatedListCall) IfNoneMatch(entityTag string) *MachineTypesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *MachineTypesAggregatedListCall) Context(ctx context.Context) *MachineTypesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MachineTypesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MachineTypesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/machineTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.machineTypes.aggregatedList" call.
// Exactly one of *MachineTypeAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *MachineTypeAggregatedList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MachineTypesAggregatedListCall) Do(opts ...googleapi.CallOption) (*MachineTypeAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MachineTypeAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of machine types. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.machineTypes.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/machineTypes",
	//   "response": {
	//     "$ref": "MachineTypeAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *MachineTypesAggregatedListCall) Pages(ctx context.Context, f func(*MachineTypeAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.machineTypes.get":

type MachineTypesGetCall struct {
	s            *Service
	project      string
	zone         string
	machineType  string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified machine type. Gets a list of available
// machine types by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/machineTypes/get
func (r *MachineTypesService) Get(project string, zone string, machineType string) *MachineTypesGetCall {
	c := &MachineTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.machineType = machineType
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MachineTypesGetCall) Fields(s ...googleapi.Field) *MachineTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *MachineTypesGetCall) IfNoneMatch(entityTag string) *MachineTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *MachineTypesGetCall) Context(ctx context.Context) *MachineTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MachineTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MachineTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/machineTypes/{machineType}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"zone":        c.zone,
		"machineType": c.machineType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.machineTypes.get" call.
// Exactly one of *MachineType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *MachineType.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *MachineTypesGetCall) Do(opts ...googleapi.CallOption) (*MachineType, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MachineType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified machine type. Gets a list of available machine types by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.machineTypes.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "machineType"
	//   ],
	//   "parameters": {
	//     "machineType": {
	//       "description": "Name of the machine type to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/machineTypes/{machineType}",
	//   "response": {
	//     "$ref": "MachineType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.machineTypes.list":

type MachineTypesListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of machine types available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/machineTypes/list
func (r *MachineTypesService) List(project string, zone string) *MachineTypesListCall {
	c := &MachineTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *MachineTypesListCall) Filter(filter string) *MachineTypesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *MachineTypesListCall) MaxResults(maxResults int64) *MachineTypesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *MachineTypesListCall) OrderBy(orderBy string) *MachineTypesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *MachineTypesListCall) PageToken(pageToken string) *MachineTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MachineTypesListCall) Fields(s ...googleapi.Field) *MachineTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *MachineTypesListCall) IfNoneMatch(entityTag string) *MachineTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *MachineTypesListCall) Context(ctx context.Context) *MachineTypesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MachineTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MachineTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/machineTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.machineTypes.list" call.
// Exactly one of *MachineTypeList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *MachineTypeList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MachineTypesListCall) Do(opts ...googleapi.CallOption) (*MachineTypeList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MachineTypeList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of machine types available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.machineTypes.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/machineTypes",
	//   "response": {
	//     "$ref": "MachineTypeList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *MachineTypesListCall) Pages(ctx context.Context, f func(*MachineTypeList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.networkEndpointGroups.aggregatedList":

type NetworkEndpointGroupsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of network endpoint groups and
// sorts them by zone. (== suppress_warning http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) AggregatedList(project string) *NetworkEndpointGroupsAggregatedListCall {
	c := &NetworkEndpointGroupsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NetworkEndpointGroupsAggregatedListCall) Filter(filter string) *NetworkEndpointGroupsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NetworkEndpointGroupsAggregatedListCall) MaxResults(maxResults int64) *NetworkEndpointGroupsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NetworkEndpointGroupsAggregatedListCall) OrderBy(orderBy string) *NetworkEndpointGroupsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NetworkEndpointGroupsAggregatedListCall) PageToken(pageToken string) *NetworkEndpointGroupsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsAggregatedListCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NetworkEndpointGroupsAggregatedListCall) IfNoneMatch(entityTag string) *NetworkEndpointGroupsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsAggregatedListCall) Context(ctx context.Context) *NetworkEndpointGroupsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/networkEndpointGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.aggregatedList" call.
// Exactly one of *NetworkEndpointGroupAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *NetworkEndpointGroupAggregatedList.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *NetworkEndpointGroupsAggregatedListCall) Do(opts ...googleapi.CallOption) (*NetworkEndpointGroupAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NetworkEndpointGroupAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of network endpoint groups and sorts them by zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.networkEndpointGroups.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/networkEndpointGroups",
	//   "response": {
	//     "$ref": "NetworkEndpointGroupAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NetworkEndpointGroupsAggregatedListCall) Pages(ctx context.Context, f func(*NetworkEndpointGroupAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.networkEndpointGroups.attachNetworkEndpoints":

type NetworkEndpointGroupsAttachNetworkEndpointsCall struct {
	s                                           *Service
	project                                     string
	zone                                        string
	networkEndpointGroup                        string
	networkendpointgroupsattachendpointsrequest *NetworkEndpointGroupsAttachEndpointsRequest
	urlParams_                                  gensupport.URLParams
	ctx_                                        context.Context
	header_                                     http.Header
}

// AttachNetworkEndpoints: Attach a list of network endpoints to the
// specified network endpoint group. (== suppress_warning
// http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) AttachNetworkEndpoints(project string, zone string, networkEndpointGroup string, networkendpointgroupsattachendpointsrequest *NetworkEndpointGroupsAttachEndpointsRequest) *NetworkEndpointGroupsAttachNetworkEndpointsCall {
	c := &NetworkEndpointGroupsAttachNetworkEndpointsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.networkEndpointGroup = networkEndpointGroup
	c.networkendpointgroupsattachendpointsrequest = networkendpointgroupsattachendpointsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworkEndpointGroupsAttachNetworkEndpointsCall) RequestId(requestId string) *NetworkEndpointGroupsAttachNetworkEndpointsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsAttachNetworkEndpointsCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsAttachNetworkEndpointsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsAttachNetworkEndpointsCall) Context(ctx context.Context) *NetworkEndpointGroupsAttachNetworkEndpointsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsAttachNetworkEndpointsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsAttachNetworkEndpointsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networkendpointgroupsattachendpointsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}/attachNetworkEndpoints")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"networkEndpointGroup": c.networkEndpointGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.attachNetworkEndpoints" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworkEndpointGroupsAttachNetworkEndpointsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Attach a list of network endpoints to the specified network endpoint group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networkEndpointGroups.attachNetworkEndpoints",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "networkEndpointGroup"
	//   ],
	//   "parameters": {
	//     "networkEndpointGroup": {
	//       "description": "The name of the network endpoint group where you are attaching network endpoints to. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the network endpoint group is located. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}/attachNetworkEndpoints",
	//   "request": {
	//     "$ref": "NetworkEndpointGroupsAttachEndpointsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networkEndpointGroups.delete":

type NetworkEndpointGroupsDeleteCall struct {
	s                    *Service
	project              string
	zone                 string
	networkEndpointGroup string
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Delete: Deletes the specified network endpoint group. The network
// endpoints in the NEG and the VM instances they belong to are not
// terminated when the NEG is deleted. Note that the NEG cannot be
// deleted if there are backend services referencing it. (==
// suppress_warning http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) Delete(project string, zone string, networkEndpointGroup string) *NetworkEndpointGroupsDeleteCall {
	c := &NetworkEndpointGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.networkEndpointGroup = networkEndpointGroup
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworkEndpointGroupsDeleteCall) RequestId(requestId string) *NetworkEndpointGroupsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsDeleteCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsDeleteCall) Context(ctx context.Context) *NetworkEndpointGroupsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"networkEndpointGroup": c.networkEndpointGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworkEndpointGroupsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified network endpoint group. The network endpoints in the NEG and the VM instances they belong to are not terminated when the NEG is deleted. Note that the NEG cannot be deleted if there are backend services referencing it. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.networkEndpointGroups.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "networkEndpointGroup"
	//   ],
	//   "parameters": {
	//     "networkEndpointGroup": {
	//       "description": "The name of the network endpoint group to delete. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the network endpoint group is located. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networkEndpointGroups.detachNetworkEndpoints":

type NetworkEndpointGroupsDetachNetworkEndpointsCall struct {
	s                                           *Service
	project                                     string
	zone                                        string
	networkEndpointGroup                        string
	networkendpointgroupsdetachendpointsrequest *NetworkEndpointGroupsDetachEndpointsRequest
	urlParams_                                  gensupport.URLParams
	ctx_                                        context.Context
	header_                                     http.Header
}

// DetachNetworkEndpoints: Detach a list of network endpoints from the
// specified network endpoint group. (== suppress_warning
// http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) DetachNetworkEndpoints(project string, zone string, networkEndpointGroup string, networkendpointgroupsdetachendpointsrequest *NetworkEndpointGroupsDetachEndpointsRequest) *NetworkEndpointGroupsDetachNetworkEndpointsCall {
	c := &NetworkEndpointGroupsDetachNetworkEndpointsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.networkEndpointGroup = networkEndpointGroup
	c.networkendpointgroupsdetachendpointsrequest = networkendpointgroupsdetachendpointsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworkEndpointGroupsDetachNetworkEndpointsCall) RequestId(requestId string) *NetworkEndpointGroupsDetachNetworkEndpointsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsDetachNetworkEndpointsCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsDetachNetworkEndpointsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsDetachNetworkEndpointsCall) Context(ctx context.Context) *NetworkEndpointGroupsDetachNetworkEndpointsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsDetachNetworkEndpointsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsDetachNetworkEndpointsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networkendpointgroupsdetachendpointsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}/detachNetworkEndpoints")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"networkEndpointGroup": c.networkEndpointGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.detachNetworkEndpoints" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworkEndpointGroupsDetachNetworkEndpointsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Detach a list of network endpoints from the specified network endpoint group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networkEndpointGroups.detachNetworkEndpoints",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "networkEndpointGroup"
	//   ],
	//   "parameters": {
	//     "networkEndpointGroup": {
	//       "description": "The name of the network endpoint group where you are removing network endpoints. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the network endpoint group is located. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}/detachNetworkEndpoints",
	//   "request": {
	//     "$ref": "NetworkEndpointGroupsDetachEndpointsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networkEndpointGroups.get":

type NetworkEndpointGroupsGetCall struct {
	s                    *Service
	project              string
	zone                 string
	networkEndpointGroup string
	urlParams_           gensupport.URLParams
	ifNoneMatch_         string
	ctx_                 context.Context
	header_              http.Header
}

// Get: Returns the specified network endpoint group. Gets a list of
// available network endpoint groups by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) Get(project string, zone string, networkEndpointGroup string) *NetworkEndpointGroupsGetCall {
	c := &NetworkEndpointGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.networkEndpointGroup = networkEndpointGroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsGetCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NetworkEndpointGroupsGetCall) IfNoneMatch(entityTag string) *NetworkEndpointGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsGetCall) Context(ctx context.Context) *NetworkEndpointGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"networkEndpointGroup": c.networkEndpointGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.get" call.
// Exactly one of *NetworkEndpointGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NetworkEndpointGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NetworkEndpointGroupsGetCall) Do(opts ...googleapi.CallOption) (*NetworkEndpointGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NetworkEndpointGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified network endpoint group. Gets a list of available network endpoint groups by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.networkEndpointGroups.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "networkEndpointGroup"
	//   ],
	//   "parameters": {
	//     "networkEndpointGroup": {
	//       "description": "The name of the network endpoint group. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the network endpoint group is located. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}",
	//   "response": {
	//     "$ref": "NetworkEndpointGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.networkEndpointGroups.insert":

type NetworkEndpointGroupsInsertCall struct {
	s                    *Service
	project              string
	zone                 string
	networkendpointgroup *NetworkEndpointGroup
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Insert: Creates a network endpoint group in the specified project
// using the parameters that are included in the request. (==
// suppress_warning http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) Insert(project string, zone string, networkendpointgroup *NetworkEndpointGroup) *NetworkEndpointGroupsInsertCall {
	c := &NetworkEndpointGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.networkendpointgroup = networkendpointgroup
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworkEndpointGroupsInsertCall) RequestId(requestId string) *NetworkEndpointGroupsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsInsertCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsInsertCall) Context(ctx context.Context) *NetworkEndpointGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networkendpointgroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworkEndpointGroupsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a network endpoint group in the specified project using the parameters that are included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networkEndpointGroups.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where you want to create the network endpoint group. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups",
	//   "request": {
	//     "$ref": "NetworkEndpointGroup"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networkEndpointGroups.list":

type NetworkEndpointGroupsListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of network endpoint groups that are located
// in the specified project and zone. (== suppress_warning
// http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) List(project string, zone string) *NetworkEndpointGroupsListCall {
	c := &NetworkEndpointGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NetworkEndpointGroupsListCall) Filter(filter string) *NetworkEndpointGroupsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NetworkEndpointGroupsListCall) MaxResults(maxResults int64) *NetworkEndpointGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NetworkEndpointGroupsListCall) OrderBy(orderBy string) *NetworkEndpointGroupsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NetworkEndpointGroupsListCall) PageToken(pageToken string) *NetworkEndpointGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsListCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NetworkEndpointGroupsListCall) IfNoneMatch(entityTag string) *NetworkEndpointGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsListCall) Context(ctx context.Context) *NetworkEndpointGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.list" call.
// Exactly one of *NetworkEndpointGroupList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *NetworkEndpointGroupList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NetworkEndpointGroupsListCall) Do(opts ...googleapi.CallOption) (*NetworkEndpointGroupList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NetworkEndpointGroupList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of network endpoint groups that are located in the specified project and zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.networkEndpointGroups.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the network endpoint group is located. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups",
	//   "response": {
	//     "$ref": "NetworkEndpointGroupList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NetworkEndpointGroupsListCall) Pages(ctx context.Context, f func(*NetworkEndpointGroupList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.networkEndpointGroups.listNetworkEndpoints":

type NetworkEndpointGroupsListNetworkEndpointsCall struct {
	s                                         *Service
	project                                   string
	zone                                      string
	networkEndpointGroup                      string
	networkendpointgroupslistendpointsrequest *NetworkEndpointGroupsListEndpointsRequest
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// ListNetworkEndpoints: Lists the network endpoints in the specified
// network endpoint group. (== suppress_warning http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) ListNetworkEndpoints(project string, zone string, networkEndpointGroup string, networkendpointgroupslistendpointsrequest *NetworkEndpointGroupsListEndpointsRequest) *NetworkEndpointGroupsListNetworkEndpointsCall {
	c := &NetworkEndpointGroupsListNetworkEndpointsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.networkEndpointGroup = networkEndpointGroup
	c.networkendpointgroupslistendpointsrequest = networkendpointgroupslistendpointsrequest
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) Filter(filter string) *NetworkEndpointGroupsListNetworkEndpointsCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) MaxResults(maxResults int64) *NetworkEndpointGroupsListNetworkEndpointsCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) OrderBy(orderBy string) *NetworkEndpointGroupsListNetworkEndpointsCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) PageToken(pageToken string) *NetworkEndpointGroupsListNetworkEndpointsCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsListNetworkEndpointsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) Context(ctx context.Context) *NetworkEndpointGroupsListNetworkEndpointsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsListNetworkEndpointsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networkendpointgroupslistendpointsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}/listNetworkEndpoints")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"zone":                 c.zone,
		"networkEndpointGroup": c.networkEndpointGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.listNetworkEndpoints" call.
// Exactly one of *NetworkEndpointGroupsListNetworkEndpoints or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *NetworkEndpointGroupsListNetworkEndpoints.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) Do(opts ...googleapi.CallOption) (*NetworkEndpointGroupsListNetworkEndpoints, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NetworkEndpointGroupsListNetworkEndpoints{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists the network endpoints in the specified network endpoint group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networkEndpointGroups.listNetworkEndpoints",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "networkEndpointGroup"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "networkEndpointGroup": {
	//       "description": "The name of the network endpoint group from which you want to generate a list of included network endpoints. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone where the network endpoint group is located. It should comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups/{networkEndpointGroup}/listNetworkEndpoints",
	//   "request": {
	//     "$ref": "NetworkEndpointGroupsListEndpointsRequest"
	//   },
	//   "response": {
	//     "$ref": "NetworkEndpointGroupsListNetworkEndpoints"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NetworkEndpointGroupsListNetworkEndpointsCall) Pages(ctx context.Context, f func(*NetworkEndpointGroupsListNetworkEndpoints) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.networkEndpointGroups.testIamPermissions":

type NetworkEndpointGroupsTestIamPermissionsCall struct {
	s                      *Service
	project                string
	zone                   string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *NetworkEndpointGroupsService) TestIamPermissions(project string, zone string, resource string, testpermissionsrequest *TestPermissionsRequest) *NetworkEndpointGroupsTestIamPermissionsCall {
	c := &NetworkEndpointGroupsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworkEndpointGroupsTestIamPermissionsCall) Fields(s ...googleapi.Field) *NetworkEndpointGroupsTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworkEndpointGroupsTestIamPermissionsCall) Context(ctx context.Context) *NetworkEndpointGroupsTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworkEndpointGroupsTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworkEndpointGroupsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/networkEndpointGroups/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networkEndpointGroups.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NetworkEndpointGroupsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networkEndpointGroups.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/networkEndpointGroups/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.networks.addPeering":

type NetworksAddPeeringCall struct {
	s                         *Service
	project                   string
	network                   string
	networksaddpeeringrequest *NetworksAddPeeringRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// AddPeering: Adds a peering to the specified network. (==
// suppress_warning http-rest-shadowed ==)
func (r *NetworksService) AddPeering(project string, network string, networksaddpeeringrequest *NetworksAddPeeringRequest) *NetworksAddPeeringCall {
	c := &NetworksAddPeeringCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	c.networksaddpeeringrequest = networksaddpeeringrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworksAddPeeringCall) RequestId(requestId string) *NetworksAddPeeringCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksAddPeeringCall) Fields(s ...googleapi.Field) *NetworksAddPeeringCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksAddPeeringCall) Context(ctx context.Context) *NetworksAddPeeringCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksAddPeeringCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksAddPeeringCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networksaddpeeringrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}/addPeering")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"network": c.network,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.addPeering" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksAddPeeringCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds a peering to the specified network. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networks.addPeering",
	//   "parameterOrder": [
	//     "project",
	//     "network"
	//   ],
	//   "parameters": {
	//     "network": {
	//       "description": "Name of the network resource to add peering to.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks/{network}/addPeering",
	//   "request": {
	//     "$ref": "NetworksAddPeeringRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networks.delete":

type NetworksDeleteCall struct {
	s          *Service
	project    string
	network    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified network. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/networks/delete
func (r *NetworksService) Delete(project string, network string) *NetworksDeleteCall {
	c := &NetworksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworksDeleteCall) RequestId(requestId string) *NetworksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksDeleteCall) Fields(s ...googleapi.Field) *NetworksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksDeleteCall) Context(ctx context.Context) *NetworksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"network": c.network,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified network. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.networks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "network"
	//   ],
	//   "parameters": {
	//     "network": {
	//       "description": "Name of the network to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks/{network}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networks.get":

type NetworksGetCall struct {
	s            *Service
	project      string
	network      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified network. Gets a list of available networks
// by making a list() request. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/networks/get
func (r *NetworksService) Get(project string, network string) *NetworksGetCall {
	c := &NetworksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksGetCall) Fields(s ...googleapi.Field) *NetworksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NetworksGetCall) IfNoneMatch(entityTag string) *NetworksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksGetCall) Context(ctx context.Context) *NetworksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"network": c.network,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.get" call.
// Exactly one of *Network or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Network.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *NetworksGetCall) Do(opts ...googleapi.CallOption) (*Network, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Network{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified network. Gets a list of available networks by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.networks.get",
	//   "parameterOrder": [
	//     "project",
	//     "network"
	//   ],
	//   "parameters": {
	//     "network": {
	//       "description": "Name of the network to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks/{network}",
	//   "response": {
	//     "$ref": "Network"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.networks.insert":

type NetworksInsertCall struct {
	s          *Service
	project    string
	network    *Network
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a network in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/networks/insert
func (r *NetworksService) Insert(project string, network *Network) *NetworksInsertCall {
	c := &NetworksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworksInsertCall) RequestId(requestId string) *NetworksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksInsertCall) Fields(s ...googleapi.Field) *NetworksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksInsertCall) Context(ctx context.Context) *NetworksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.network)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a network in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networks.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks",
	//   "request": {
	//     "$ref": "Network"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networks.list":

type NetworksListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of networks available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/networks/list
func (r *NetworksService) List(project string) *NetworksListCall {
	c := &NetworksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NetworksListCall) Filter(filter string) *NetworksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NetworksListCall) MaxResults(maxResults int64) *NetworksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NetworksListCall) OrderBy(orderBy string) *NetworksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NetworksListCall) PageToken(pageToken string) *NetworksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksListCall) Fields(s ...googleapi.Field) *NetworksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NetworksListCall) IfNoneMatch(entityTag string) *NetworksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksListCall) Context(ctx context.Context) *NetworksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.list" call.
// Exactly one of *NetworkList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *NetworkList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksListCall) Do(opts ...googleapi.CallOption) (*NetworkList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NetworkList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of networks available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.networks.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks",
	//   "response": {
	//     "$ref": "NetworkList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NetworksListCall) Pages(ctx context.Context, f func(*NetworkList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.networks.patch":

type NetworksPatchCall struct {
	s          *Service
	project    string
	network    string
	network2   *Network
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Patches the specified network with the data included in the
// request. Only the following fields can be modified:
// routingConfig.routingMode. (== suppress_warning http-rest-shadowed
// ==)
func (r *NetworksService) Patch(project string, network string, network2 *Network) *NetworksPatchCall {
	c := &NetworksPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	c.network2 = network2
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworksPatchCall) RequestId(requestId string) *NetworksPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksPatchCall) Fields(s ...googleapi.Field) *NetworksPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksPatchCall) Context(ctx context.Context) *NetworksPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.network2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"network": c.network,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified network with the data included in the request. Only the following fields can be modified: routingConfig.routingMode. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.networks.patch",
	//   "parameterOrder": [
	//     "project",
	//     "network"
	//   ],
	//   "parameters": {
	//     "network": {
	//       "description": "Name of the network to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks/{network}",
	//   "request": {
	//     "$ref": "Network"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networks.removePeering":

type NetworksRemovePeeringCall struct {
	s                            *Service
	project                      string
	network                      string
	networksremovepeeringrequest *NetworksRemovePeeringRequest
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// RemovePeering: Removes a peering from the specified network. (==
// suppress_warning http-rest-shadowed ==)
func (r *NetworksService) RemovePeering(project string, network string, networksremovepeeringrequest *NetworksRemovePeeringRequest) *NetworksRemovePeeringCall {
	c := &NetworksRemovePeeringCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	c.networksremovepeeringrequest = networksremovepeeringrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworksRemovePeeringCall) RequestId(requestId string) *NetworksRemovePeeringCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksRemovePeeringCall) Fields(s ...googleapi.Field) *NetworksRemovePeeringCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksRemovePeeringCall) Context(ctx context.Context) *NetworksRemovePeeringCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksRemovePeeringCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksRemovePeeringCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networksremovepeeringrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}/removePeering")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"network": c.network,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.removePeering" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksRemovePeeringCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Removes a peering from the specified network. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networks.removePeering",
	//   "parameterOrder": [
	//     "project",
	//     "network"
	//   ],
	//   "parameters": {
	//     "network": {
	//       "description": "Name of the network resource to remove peering from.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks/{network}/removePeering",
	//   "request": {
	//     "$ref": "NetworksRemovePeeringRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networks.switchToCustomMode":

type NetworksSwitchToCustomModeCall struct {
	s          *Service
	project    string
	network    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SwitchToCustomMode: Switches the network mode from auto subnet mode
// to custom subnet mode. (== suppress_warning http-rest-shadowed ==)
func (r *NetworksService) SwitchToCustomMode(project string, network string) *NetworksSwitchToCustomModeCall {
	c := &NetworksSwitchToCustomModeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworksSwitchToCustomModeCall) RequestId(requestId string) *NetworksSwitchToCustomModeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksSwitchToCustomModeCall) Fields(s ...googleapi.Field) *NetworksSwitchToCustomModeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksSwitchToCustomModeCall) Context(ctx context.Context) *NetworksSwitchToCustomModeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksSwitchToCustomModeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksSwitchToCustomModeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}/switchToCustomMode")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"network": c.network,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.switchToCustomMode" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksSwitchToCustomModeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Switches the network mode from auto subnet mode to custom subnet mode. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.networks.switchToCustomMode",
	//   "parameterOrder": [
	//     "project",
	//     "network"
	//   ],
	//   "parameters": {
	//     "network": {
	//       "description": "Name of the network to be updated.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks/{network}/switchToCustomMode",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.networks.updatePeering":

type NetworksUpdatePeeringCall struct {
	s                            *Service
	project                      string
	network                      string
	networksupdatepeeringrequest *NetworksUpdatePeeringRequest
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// UpdatePeering: Updates the specified network peering with the data
// included in the request Only the following fields can be modified:
// NetworkPeering.export_custom_routes, and
// NetworkPeering.import_custom_routes (== suppress_warning
// http-rest-shadowed ==)
func (r *NetworksService) UpdatePeering(project string, network string, networksupdatepeeringrequest *NetworksUpdatePeeringRequest) *NetworksUpdatePeeringCall {
	c := &NetworksUpdatePeeringCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.network = network
	c.networksupdatepeeringrequest = networksupdatepeeringrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NetworksUpdatePeeringCall) RequestId(requestId string) *NetworksUpdatePeeringCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NetworksUpdatePeeringCall) Fields(s ...googleapi.Field) *NetworksUpdatePeeringCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NetworksUpdatePeeringCall) Context(ctx context.Context) *NetworksUpdatePeeringCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NetworksUpdatePeeringCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NetworksUpdatePeeringCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.networksupdatepeeringrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}/updatePeering")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"network": c.network,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.networks.updatePeering" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NetworksUpdatePeeringCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified network peering with the data included in the request Only the following fields can be modified: NetworkPeering.export_custom_routes, and NetworkPeering.import_custom_routes (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.networks.updatePeering",
	//   "parameterOrder": [
	//     "project",
	//     "network"
	//   ],
	//   "parameters": {
	//     "network": {
	//       "description": "Name of the network resource which the updated peering is belonging to.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/networks/{network}/updatePeering",
	//   "request": {
	//     "$ref": "NetworksUpdatePeeringRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeGroups.addNodes":

type NodeGroupsAddNodesCall struct {
	s                         *Service
	project                   string
	zone                      string
	nodeGroup                 string
	nodegroupsaddnodesrequest *NodeGroupsAddNodesRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// AddNodes: Adds specified number of nodes to the node group. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeGroupsService) AddNodes(project string, zone string, nodeGroup string, nodegroupsaddnodesrequest *NodeGroupsAddNodesRequest) *NodeGroupsAddNodesCall {
	c := &NodeGroupsAddNodesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.nodeGroup = nodeGroup
	c.nodegroupsaddnodesrequest = nodegroupsaddnodesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NodeGroupsAddNodesCall) RequestId(requestId string) *NodeGroupsAddNodesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsAddNodesCall) Fields(s ...googleapi.Field) *NodeGroupsAddNodesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsAddNodesCall) Context(ctx context.Context) *NodeGroupsAddNodesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsAddNodesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsAddNodesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.nodegroupsaddnodesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{nodeGroup}/addNodes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"nodeGroup": c.nodeGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.addNodes" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeGroupsAddNodesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds specified number of nodes to the node group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeGroups.addNodes",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "nodeGroup"
	//   ],
	//   "parameters": {
	//     "nodeGroup": {
	//       "description": "Name of the NodeGroup resource.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{nodeGroup}/addNodes",
	//   "request": {
	//     "$ref": "NodeGroupsAddNodesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeGroups.aggregatedList":

type NodeGroupsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of node groups. Note:
// use nodeGroups.listNodes for more details about each group. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeGroupsService) AggregatedList(project string) *NodeGroupsAggregatedListCall {
	c := &NodeGroupsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NodeGroupsAggregatedListCall) Filter(filter string) *NodeGroupsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NodeGroupsAggregatedListCall) MaxResults(maxResults int64) *NodeGroupsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NodeGroupsAggregatedListCall) OrderBy(orderBy string) *NodeGroupsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NodeGroupsAggregatedListCall) PageToken(pageToken string) *NodeGroupsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsAggregatedListCall) Fields(s ...googleapi.Field) *NodeGroupsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeGroupsAggregatedListCall) IfNoneMatch(entityTag string) *NodeGroupsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsAggregatedListCall) Context(ctx context.Context) *NodeGroupsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/nodeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.aggregatedList" call.
// Exactly one of *NodeGroupAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NodeGroupAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeGroupsAggregatedListCall) Do(opts ...googleapi.CallOption) (*NodeGroupAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeGroupAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of node groups. Note: use nodeGroups.listNodes for more details about each group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeGroups.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/nodeGroups",
	//   "response": {
	//     "$ref": "NodeGroupAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NodeGroupsAggregatedListCall) Pages(ctx context.Context, f func(*NodeGroupAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.nodeGroups.delete":

type NodeGroupsDeleteCall struct {
	s          *Service
	project    string
	zone       string
	nodeGroup  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified NodeGroup resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeGroupsService) Delete(project string, zone string, nodeGroup string) *NodeGroupsDeleteCall {
	c := &NodeGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.nodeGroup = nodeGroup
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NodeGroupsDeleteCall) RequestId(requestId string) *NodeGroupsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsDeleteCall) Fields(s ...googleapi.Field) *NodeGroupsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsDeleteCall) Context(ctx context.Context) *NodeGroupsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{nodeGroup}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"nodeGroup": c.nodeGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeGroupsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified NodeGroup resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.nodeGroups.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "nodeGroup"
	//   ],
	//   "parameters": {
	//     "nodeGroup": {
	//       "description": "Name of the NodeGroup resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{nodeGroup}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeGroups.deleteNodes":

type NodeGroupsDeleteNodesCall struct {
	s                            *Service
	project                      string
	zone                         string
	nodeGroup                    string
	nodegroupsdeletenodesrequest *NodeGroupsDeleteNodesRequest
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// DeleteNodes: Deletes specified nodes from the node group. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeGroupsService) DeleteNodes(project string, zone string, nodeGroup string, nodegroupsdeletenodesrequest *NodeGroupsDeleteNodesRequest) *NodeGroupsDeleteNodesCall {
	c := &NodeGroupsDeleteNodesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.nodeGroup = nodeGroup
	c.nodegroupsdeletenodesrequest = nodegroupsdeletenodesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NodeGroupsDeleteNodesCall) RequestId(requestId string) *NodeGroupsDeleteNodesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsDeleteNodesCall) Fields(s ...googleapi.Field) *NodeGroupsDeleteNodesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsDeleteNodesCall) Context(ctx context.Context) *NodeGroupsDeleteNodesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsDeleteNodesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsDeleteNodesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.nodegroupsdeletenodesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{nodeGroup}/deleteNodes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"nodeGroup": c.nodeGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.deleteNodes" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeGroupsDeleteNodesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes specified nodes from the node group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeGroups.deleteNodes",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "nodeGroup"
	//   ],
	//   "parameters": {
	//     "nodeGroup": {
	//       "description": "Name of the NodeGroup resource whose nodes will be deleted.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{nodeGroup}/deleteNodes",
	//   "request": {
	//     "$ref": "NodeGroupsDeleteNodesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeGroups.get":

type NodeGroupsGetCall struct {
	s            *Service
	project      string
	zone         string
	nodeGroup    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified NodeGroup. Get a list of available
// NodeGroups by making a list() request. Note: the "nodes" field should
// not be used. Use nodeGroups.listNodes instead. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeGroupsService) Get(project string, zone string, nodeGroup string) *NodeGroupsGetCall {
	c := &NodeGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.nodeGroup = nodeGroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsGetCall) Fields(s ...googleapi.Field) *NodeGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeGroupsGetCall) IfNoneMatch(entityTag string) *NodeGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsGetCall) Context(ctx context.Context) *NodeGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{nodeGroup}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"nodeGroup": c.nodeGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.get" call.
// Exactly one of *NodeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *NodeGroup.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeGroupsGetCall) Do(opts ...googleapi.CallOption) (*NodeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified NodeGroup. Get a list of available NodeGroups by making a list() request. Note: the \"nodes\" field should not be used. Use nodeGroups.listNodes instead. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeGroups.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "nodeGroup"
	//   ],
	//   "parameters": {
	//     "nodeGroup": {
	//       "description": "Name of the node group to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{nodeGroup}",
	//   "response": {
	//     "$ref": "NodeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.nodeGroups.getIamPolicy":

type NodeGroupsGetIamPolicyCall struct {
	s            *Service
	project      string
	zone         string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeGroupsService) GetIamPolicy(project string, zone string, resource string) *NodeGroupsGetIamPolicyCall {
	c := &NodeGroupsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsGetIamPolicyCall) Fields(s ...googleapi.Field) *NodeGroupsGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeGroupsGetIamPolicyCall) IfNoneMatch(entityTag string) *NodeGroupsGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsGetIamPolicyCall) Context(ctx context.Context) *NodeGroupsGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *NodeGroupsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeGroups.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.nodeGroups.insert":

type NodeGroupsInsertCall struct {
	s          *Service
	project    string
	zone       string
	nodegroup  *NodeGroup
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a NodeGroup resource in the specified project using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeGroupsService) Insert(project string, zone string, initialNodeCount int64, nodegroup *NodeGroup) *NodeGroupsInsertCall {
	c := &NodeGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.urlParams_.Set("initialNodeCount", fmt.Sprint(initialNodeCount))
	c.nodegroup = nodegroup
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NodeGroupsInsertCall) RequestId(requestId string) *NodeGroupsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsInsertCall) Fields(s ...googleapi.Field) *NodeGroupsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsInsertCall) Context(ctx context.Context) *NodeGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.nodegroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeGroupsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a NodeGroup resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeGroups.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "initialNodeCount"
	//   ],
	//   "parameters": {
	//     "initialNodeCount": {
	//       "description": "Initial count of nodes in the node group.",
	//       "format": "int32",
	//       "location": "query",
	//       "required": true,
	//       "type": "integer"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups",
	//   "request": {
	//     "$ref": "NodeGroup"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeGroups.list":

type NodeGroupsListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of node groups available to the specified
// project. Note: use nodeGroups.listNodes for more details about each
// group. (== suppress_warning http-rest-shadowed ==)
func (r *NodeGroupsService) List(project string, zone string) *NodeGroupsListCall {
	c := &NodeGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NodeGroupsListCall) Filter(filter string) *NodeGroupsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NodeGroupsListCall) MaxResults(maxResults int64) *NodeGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NodeGroupsListCall) OrderBy(orderBy string) *NodeGroupsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NodeGroupsListCall) PageToken(pageToken string) *NodeGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsListCall) Fields(s ...googleapi.Field) *NodeGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeGroupsListCall) IfNoneMatch(entityTag string) *NodeGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsListCall) Context(ctx context.Context) *NodeGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.list" call.
// Exactly one of *NodeGroupList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *NodeGroupList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeGroupsListCall) Do(opts ...googleapi.CallOption) (*NodeGroupList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeGroupList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of node groups available to the specified project. Note: use nodeGroups.listNodes for more details about each group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeGroups.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups",
	//   "response": {
	//     "$ref": "NodeGroupList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NodeGroupsListCall) Pages(ctx context.Context, f func(*NodeGroupList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.nodeGroups.listNodes":

type NodeGroupsListNodesCall struct {
	s          *Service
	project    string
	zone       string
	nodeGroup  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// ListNodes: Lists nodes in the node group. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeGroupsService) ListNodes(project string, zone string, nodeGroup string) *NodeGroupsListNodesCall {
	c := &NodeGroupsListNodesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.nodeGroup = nodeGroup
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NodeGroupsListNodesCall) Filter(filter string) *NodeGroupsListNodesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NodeGroupsListNodesCall) MaxResults(maxResults int64) *NodeGroupsListNodesCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NodeGroupsListNodesCall) OrderBy(orderBy string) *NodeGroupsListNodesCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NodeGroupsListNodesCall) PageToken(pageToken string) *NodeGroupsListNodesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsListNodesCall) Fields(s ...googleapi.Field) *NodeGroupsListNodesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsListNodesCall) Context(ctx context.Context) *NodeGroupsListNodesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsListNodesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsListNodesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{nodeGroup}/listNodes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"nodeGroup": c.nodeGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.listNodes" call.
// Exactly one of *NodeGroupsListNodes or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NodeGroupsListNodes.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeGroupsListNodesCall) Do(opts ...googleapi.CallOption) (*NodeGroupsListNodes, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeGroupsListNodes{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists nodes in the node group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeGroups.listNodes",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "nodeGroup"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "nodeGroup": {
	//       "description": "Name of the NodeGroup resource whose nodes you want to list.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{nodeGroup}/listNodes",
	//   "response": {
	//     "$ref": "NodeGroupsListNodes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NodeGroupsListNodesCall) Pages(ctx context.Context, f func(*NodeGroupsListNodes) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.nodeGroups.setIamPolicy":

type NodeGroupsSetIamPolicyCall struct {
	s                    *Service
	project              string
	zone                 string
	resource             string
	zonesetpolicyrequest *ZoneSetPolicyRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeGroupsService) SetIamPolicy(project string, zone string, resource string, zonesetpolicyrequest *ZoneSetPolicyRequest) *NodeGroupsSetIamPolicyCall {
	c := &NodeGroupsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.zonesetpolicyrequest = zonesetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsSetIamPolicyCall) Fields(s ...googleapi.Field) *NodeGroupsSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsSetIamPolicyCall) Context(ctx context.Context) *NodeGroupsSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.zonesetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *NodeGroupsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeGroups.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "ZoneSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeGroups.setNodeTemplate":

type NodeGroupsSetNodeTemplateCall struct {
	s                                *Service
	project                          string
	zone                             string
	nodeGroup                        string
	nodegroupssetnodetemplaterequest *NodeGroupsSetNodeTemplateRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// SetNodeTemplate: Updates the node template of the node group. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeGroupsService) SetNodeTemplate(project string, zone string, nodeGroup string, nodegroupssetnodetemplaterequest *NodeGroupsSetNodeTemplateRequest) *NodeGroupsSetNodeTemplateCall {
	c := &NodeGroupsSetNodeTemplateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.nodeGroup = nodeGroup
	c.nodegroupssetnodetemplaterequest = nodegroupssetnodetemplaterequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NodeGroupsSetNodeTemplateCall) RequestId(requestId string) *NodeGroupsSetNodeTemplateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsSetNodeTemplateCall) Fields(s ...googleapi.Field) *NodeGroupsSetNodeTemplateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsSetNodeTemplateCall) Context(ctx context.Context) *NodeGroupsSetNodeTemplateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsSetNodeTemplateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsSetNodeTemplateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.nodegroupssetnodetemplaterequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{nodeGroup}/setNodeTemplate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"nodeGroup": c.nodeGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.setNodeTemplate" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeGroupsSetNodeTemplateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the node template of the node group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeGroups.setNodeTemplate",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "nodeGroup"
	//   ],
	//   "parameters": {
	//     "nodeGroup": {
	//       "description": "Name of the NodeGroup resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{nodeGroup}/setNodeTemplate",
	//   "request": {
	//     "$ref": "NodeGroupsSetNodeTemplateRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeGroups.testIamPermissions":

type NodeGroupsTestIamPermissionsCall struct {
	s                      *Service
	project                string
	zone                   string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *NodeGroupsService) TestIamPermissions(project string, zone string, resource string, testpermissionsrequest *TestPermissionsRequest) *NodeGroupsTestIamPermissionsCall {
	c := &NodeGroupsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeGroupsTestIamPermissionsCall) Fields(s ...googleapi.Field) *NodeGroupsTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeGroupsTestIamPermissionsCall) Context(ctx context.Context) *NodeGroupsTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeGroupsTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeGroupsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeGroups/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeGroups.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeGroupsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeGroups.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeGroups/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.nodeTemplates.aggregatedList":

type NodeTemplatesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of node templates. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeTemplatesService) AggregatedList(project string) *NodeTemplatesAggregatedListCall {
	c := &NodeTemplatesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NodeTemplatesAggregatedListCall) Filter(filter string) *NodeTemplatesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NodeTemplatesAggregatedListCall) MaxResults(maxResults int64) *NodeTemplatesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NodeTemplatesAggregatedListCall) OrderBy(orderBy string) *NodeTemplatesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NodeTemplatesAggregatedListCall) PageToken(pageToken string) *NodeTemplatesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesAggregatedListCall) Fields(s ...googleapi.Field) *NodeTemplatesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeTemplatesAggregatedListCall) IfNoneMatch(entityTag string) *NodeTemplatesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesAggregatedListCall) Context(ctx context.Context) *NodeTemplatesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/nodeTemplates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.aggregatedList" call.
// Exactly one of *NodeTemplateAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *NodeTemplateAggregatedList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeTemplatesAggregatedListCall) Do(opts ...googleapi.CallOption) (*NodeTemplateAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeTemplateAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of node templates. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeTemplates.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/nodeTemplates",
	//   "response": {
	//     "$ref": "NodeTemplateAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NodeTemplatesAggregatedListCall) Pages(ctx context.Context, f func(*NodeTemplateAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.nodeTemplates.delete":

type NodeTemplatesDeleteCall struct {
	s            *Service
	project      string
	region       string
	nodeTemplate string
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Deletes the specified NodeTemplate resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeTemplatesService) Delete(project string, region string, nodeTemplate string) *NodeTemplatesDeleteCall {
	c := &NodeTemplatesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.nodeTemplate = nodeTemplate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NodeTemplatesDeleteCall) RequestId(requestId string) *NodeTemplatesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesDeleteCall) Fields(s ...googleapi.Field) *NodeTemplatesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesDeleteCall) Context(ctx context.Context) *NodeTemplatesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/nodeTemplates/{nodeTemplate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":      c.project,
		"region":       c.region,
		"nodeTemplate": c.nodeTemplate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeTemplatesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified NodeTemplate resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.nodeTemplates.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "nodeTemplate"
	//   ],
	//   "parameters": {
	//     "nodeTemplate": {
	//       "description": "Name of the NodeTemplate resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/nodeTemplates/{nodeTemplate}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeTemplates.get":

type NodeTemplatesGetCall struct {
	s            *Service
	project      string
	region       string
	nodeTemplate string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified node template. Gets a list of available
// node templates by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeTemplatesService) Get(project string, region string, nodeTemplate string) *NodeTemplatesGetCall {
	c := &NodeTemplatesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.nodeTemplate = nodeTemplate
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesGetCall) Fields(s ...googleapi.Field) *NodeTemplatesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeTemplatesGetCall) IfNoneMatch(entityTag string) *NodeTemplatesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesGetCall) Context(ctx context.Context) *NodeTemplatesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/nodeTemplates/{nodeTemplate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":      c.project,
		"region":       c.region,
		"nodeTemplate": c.nodeTemplate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.get" call.
// Exactly one of *NodeTemplate or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *NodeTemplate.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeTemplatesGetCall) Do(opts ...googleapi.CallOption) (*NodeTemplate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeTemplate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified node template. Gets a list of available node templates by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeTemplates.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "nodeTemplate"
	//   ],
	//   "parameters": {
	//     "nodeTemplate": {
	//       "description": "Name of the node template to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/nodeTemplates/{nodeTemplate}",
	//   "response": {
	//     "$ref": "NodeTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.nodeTemplates.getIamPolicy":

type NodeTemplatesGetIamPolicyCall struct {
	s            *Service
	project      string
	region       string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeTemplatesService) GetIamPolicy(project string, region string, resource string) *NodeTemplatesGetIamPolicyCall {
	c := &NodeTemplatesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesGetIamPolicyCall) Fields(s ...googleapi.Field) *NodeTemplatesGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeTemplatesGetIamPolicyCall) IfNoneMatch(entityTag string) *NodeTemplatesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesGetIamPolicyCall) Context(ctx context.Context) *NodeTemplatesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/nodeTemplates/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *NodeTemplatesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeTemplates.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/nodeTemplates/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.nodeTemplates.insert":

type NodeTemplatesInsertCall struct {
	s            *Service
	project      string
	region       string
	nodetemplate *NodeTemplate
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Insert: Creates a NodeTemplate resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeTemplatesService) Insert(project string, region string, nodetemplate *NodeTemplate) *NodeTemplatesInsertCall {
	c := &NodeTemplatesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.nodetemplate = nodetemplate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *NodeTemplatesInsertCall) RequestId(requestId string) *NodeTemplatesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesInsertCall) Fields(s ...googleapi.Field) *NodeTemplatesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesInsertCall) Context(ctx context.Context) *NodeTemplatesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.nodetemplate)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/nodeTemplates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeTemplatesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a NodeTemplate resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeTemplates.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/nodeTemplates",
	//   "request": {
	//     "$ref": "NodeTemplate"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeTemplates.list":

type NodeTemplatesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of node templates available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
func (r *NodeTemplatesService) List(project string, region string) *NodeTemplatesListCall {
	c := &NodeTemplatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NodeTemplatesListCall) Filter(filter string) *NodeTemplatesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NodeTemplatesListCall) MaxResults(maxResults int64) *NodeTemplatesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NodeTemplatesListCall) OrderBy(orderBy string) *NodeTemplatesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NodeTemplatesListCall) PageToken(pageToken string) *NodeTemplatesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesListCall) Fields(s ...googleapi.Field) *NodeTemplatesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeTemplatesListCall) IfNoneMatch(entityTag string) *NodeTemplatesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesListCall) Context(ctx context.Context) *NodeTemplatesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/nodeTemplates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.list" call.
// Exactly one of *NodeTemplateList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NodeTemplateList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeTemplatesListCall) Do(opts ...googleapi.CallOption) (*NodeTemplateList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeTemplateList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of node templates available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeTemplates.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/nodeTemplates",
	//   "response": {
	//     "$ref": "NodeTemplateList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NodeTemplatesListCall) Pages(ctx context.Context, f func(*NodeTemplateList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.nodeTemplates.setIamPolicy":

type NodeTemplatesSetIamPolicyCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	regionsetpolicyrequest *RegionSetPolicyRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeTemplatesService) SetIamPolicy(project string, region string, resource string, regionsetpolicyrequest *RegionSetPolicyRequest) *NodeTemplatesSetIamPolicyCall {
	c := &NodeTemplatesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.regionsetpolicyrequest = regionsetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesSetIamPolicyCall) Fields(s ...googleapi.Field) *NodeTemplatesSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesSetIamPolicyCall) Context(ctx context.Context) *NodeTemplatesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regionsetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/nodeTemplates/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *NodeTemplatesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeTemplates.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/nodeTemplates/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "RegionSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.nodeTemplates.testIamPermissions":

type NodeTemplatesTestIamPermissionsCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *NodeTemplatesService) TestIamPermissions(project string, region string, resource string, testpermissionsrequest *TestPermissionsRequest) *NodeTemplatesTestIamPermissionsCall {
	c := &NodeTemplatesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTemplatesTestIamPermissionsCall) Fields(s ...googleapi.Field) *NodeTemplatesTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTemplatesTestIamPermissionsCall) Context(ctx context.Context) *NodeTemplatesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTemplatesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTemplatesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/nodeTemplates/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTemplates.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeTemplatesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.nodeTemplates.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/nodeTemplates/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.nodeTypes.aggregatedList":

type NodeTypesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of node types. (==
// suppress_warning http-rest-shadowed ==)
func (r *NodeTypesService) AggregatedList(project string) *NodeTypesAggregatedListCall {
	c := &NodeTypesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NodeTypesAggregatedListCall) Filter(filter string) *NodeTypesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NodeTypesAggregatedListCall) MaxResults(maxResults int64) *NodeTypesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NodeTypesAggregatedListCall) OrderBy(orderBy string) *NodeTypesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NodeTypesAggregatedListCall) PageToken(pageToken string) *NodeTypesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTypesAggregatedListCall) Fields(s ...googleapi.Field) *NodeTypesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeTypesAggregatedListCall) IfNoneMatch(entityTag string) *NodeTypesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTypesAggregatedListCall) Context(ctx context.Context) *NodeTypesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTypesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTypesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/nodeTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTypes.aggregatedList" call.
// Exactly one of *NodeTypeAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NodeTypeAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *NodeTypesAggregatedListCall) Do(opts ...googleapi.CallOption) (*NodeTypeAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeTypeAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of node types. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeTypes.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/nodeTypes",
	//   "response": {
	//     "$ref": "NodeTypeAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NodeTypesAggregatedListCall) Pages(ctx context.Context, f func(*NodeTypeAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.nodeTypes.get":

type NodeTypesGetCall struct {
	s            *Service
	project      string
	zone         string
	nodeType     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified node type. Gets a list of available node
// types by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *NodeTypesService) Get(project string, zone string, nodeType string) *NodeTypesGetCall {
	c := &NodeTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.nodeType = nodeType
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTypesGetCall) Fields(s ...googleapi.Field) *NodeTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeTypesGetCall) IfNoneMatch(entityTag string) *NodeTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTypesGetCall) Context(ctx context.Context) *NodeTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeTypes/{nodeType}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"nodeType": c.nodeType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTypes.get" call.
// Exactly one of *NodeType or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *NodeType.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeTypesGetCall) Do(opts ...googleapi.CallOption) (*NodeType, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified node type. Gets a list of available node types by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeTypes.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "nodeType"
	//   ],
	//   "parameters": {
	//     "nodeType": {
	//       "description": "Name of the node type to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeTypes/{nodeType}",
	//   "response": {
	//     "$ref": "NodeType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.nodeTypes.list":

type NodeTypesListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of node types available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
func (r *NodeTypesService) List(project string, zone string) *NodeTypesListCall {
	c := &NodeTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *NodeTypesListCall) Filter(filter string) *NodeTypesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *NodeTypesListCall) MaxResults(maxResults int64) *NodeTypesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *NodeTypesListCall) OrderBy(orderBy string) *NodeTypesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *NodeTypesListCall) PageToken(pageToken string) *NodeTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *NodeTypesListCall) Fields(s ...googleapi.Field) *NodeTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *NodeTypesListCall) IfNoneMatch(entityTag string) *NodeTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *NodeTypesListCall) Context(ctx context.Context) *NodeTypesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *NodeTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NodeTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/nodeTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.nodeTypes.list" call.
// Exactly one of *NodeTypeList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *NodeTypeList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *NodeTypesListCall) Do(opts ...googleapi.CallOption) (*NodeTypeList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &NodeTypeList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of node types available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.nodeTypes.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/nodeTypes",
	//   "response": {
	//     "$ref": "NodeTypeList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NodeTypesListCall) Pages(ctx context.Context, f func(*NodeTypeList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.projects.disableXpnHost":

type ProjectsDisableXpnHostCall struct {
	s          *Service
	project    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DisableXpnHost: Disable this project as a shared VPC host project.
// (== suppress_warning http-rest-shadowed ==)
func (r *ProjectsService) DisableXpnHost(project string) *ProjectsDisableXpnHostCall {
	c := &ProjectsDisableXpnHostCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsDisableXpnHostCall) RequestId(requestId string) *ProjectsDisableXpnHostCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsDisableXpnHostCall) Fields(s ...googleapi.Field) *ProjectsDisableXpnHostCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsDisableXpnHostCall) Context(ctx context.Context) *ProjectsDisableXpnHostCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsDisableXpnHostCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDisableXpnHostCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/disableXpnHost")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.disableXpnHost" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsDisableXpnHostCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Disable this project as a shared VPC host project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.disableXpnHost",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/disableXpnHost",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.disableXpnResource":

type ProjectsDisableXpnResourceCall struct {
	s                                 *Service
	project                           string
	projectsdisablexpnresourcerequest *ProjectsDisableXpnResourceRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// DisableXpnResource: Disable a service resource (also known as service
// project) associated with this host project. (== suppress_warning
// http-rest-shadowed ==)
func (r *ProjectsService) DisableXpnResource(project string, projectsdisablexpnresourcerequest *ProjectsDisableXpnResourceRequest) *ProjectsDisableXpnResourceCall {
	c := &ProjectsDisableXpnResourceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.projectsdisablexpnresourcerequest = projectsdisablexpnresourcerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsDisableXpnResourceCall) RequestId(requestId string) *ProjectsDisableXpnResourceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsDisableXpnResourceCall) Fields(s ...googleapi.Field) *ProjectsDisableXpnResourceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsDisableXpnResourceCall) Context(ctx context.Context) *ProjectsDisableXpnResourceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsDisableXpnResourceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDisableXpnResourceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.projectsdisablexpnresourcerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/disableXpnResource")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.disableXpnResource" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsDisableXpnResourceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Disable a service resource (also known as service project) associated with this host project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.disableXpnResource",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/disableXpnResource",
	//   "request": {
	//     "$ref": "ProjectsDisableXpnResourceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.enableXpnHost":

type ProjectsEnableXpnHostCall struct {
	s          *Service
	project    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// EnableXpnHost: Enable this project as a shared VPC host project. (==
// suppress_warning http-rest-shadowed ==)
func (r *ProjectsService) EnableXpnHost(project string) *ProjectsEnableXpnHostCall {
	c := &ProjectsEnableXpnHostCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsEnableXpnHostCall) RequestId(requestId string) *ProjectsEnableXpnHostCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsEnableXpnHostCall) Fields(s ...googleapi.Field) *ProjectsEnableXpnHostCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsEnableXpnHostCall) Context(ctx context.Context) *ProjectsEnableXpnHostCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsEnableXpnHostCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsEnableXpnHostCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/enableXpnHost")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.enableXpnHost" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsEnableXpnHostCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Enable this project as a shared VPC host project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.enableXpnHost",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/enableXpnHost",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.enableXpnResource":

type ProjectsEnableXpnResourceCall struct {
	s                                *Service
	project                          string
	projectsenablexpnresourcerequest *ProjectsEnableXpnResourceRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// EnableXpnResource: Enable service resource (a.k.a service project)
// for a host project, so that subnets in the host project can be used
// by instances in the service project. (== suppress_warning
// http-rest-shadowed ==)
func (r *ProjectsService) EnableXpnResource(project string, projectsenablexpnresourcerequest *ProjectsEnableXpnResourceRequest) *ProjectsEnableXpnResourceCall {
	c := &ProjectsEnableXpnResourceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.projectsenablexpnresourcerequest = projectsenablexpnresourcerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsEnableXpnResourceCall) RequestId(requestId string) *ProjectsEnableXpnResourceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsEnableXpnResourceCall) Fields(s ...googleapi.Field) *ProjectsEnableXpnResourceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsEnableXpnResourceCall) Context(ctx context.Context) *ProjectsEnableXpnResourceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsEnableXpnResourceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsEnableXpnResourceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.projectsenablexpnresourcerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/enableXpnResource")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.enableXpnResource" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsEnableXpnResourceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Enable service resource (a.k.a service project) for a host project, so that subnets in the host project can be used by instances in the service project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.enableXpnResource",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/enableXpnResource",
	//   "request": {
	//     "$ref": "ProjectsEnableXpnResourceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.get":

type ProjectsGetCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified Project resource. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/projects/get
func (r *ProjectsService) Get(project string) *ProjectsGetCall {
	c := &ProjectsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsGetCall) Fields(s ...googleapi.Field) *ProjectsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsGetCall) IfNoneMatch(entityTag string) *ProjectsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsGetCall) Context(ctx context.Context) *ProjectsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.get" call.
// Exactly one of *Project or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Project.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ProjectsGetCall) Do(opts ...googleapi.CallOption) (*Project, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Project{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified Project resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.projects.get",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}",
	//   "response": {
	//     "$ref": "Project"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.projects.getXpnHost":

type ProjectsGetXpnHostCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetXpnHost: Gets the shared VPC host project that this project links
// to. May be empty if no link exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *ProjectsService) GetXpnHost(project string) *ProjectsGetXpnHostCall {
	c := &ProjectsGetXpnHostCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsGetXpnHostCall) Fields(s ...googleapi.Field) *ProjectsGetXpnHostCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsGetXpnHostCall) IfNoneMatch(entityTag string) *ProjectsGetXpnHostCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsGetXpnHostCall) Context(ctx context.Context) *ProjectsGetXpnHostCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsGetXpnHostCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetXpnHostCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/getXpnHost")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.getXpnHost" call.
// Exactly one of *Project or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Project.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ProjectsGetXpnHostCall) Do(opts ...googleapi.CallOption) (*Project, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Project{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the shared VPC host project that this project links to. May be empty if no link exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.projects.getXpnHost",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/getXpnHost",
	//   "response": {
	//     "$ref": "Project"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.getXpnResources":

type ProjectsGetXpnResourcesCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetXpnResources: Gets service resources (a.k.a service project)
// associated with this host project. (== suppress_warning
// http-rest-shadowed ==)
func (r *ProjectsService) GetXpnResources(project string) *ProjectsGetXpnResourcesCall {
	c := &ProjectsGetXpnResourcesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ProjectsGetXpnResourcesCall) Filter(filter string) *ProjectsGetXpnResourcesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ProjectsGetXpnResourcesCall) MaxResults(maxResults int64) *ProjectsGetXpnResourcesCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "order_by": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ProjectsGetXpnResourcesCall) OrderBy(orderBy string) *ProjectsGetXpnResourcesCall {
	c.urlParams_.Set("order_by", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ProjectsGetXpnResourcesCall) PageToken(pageToken string) *ProjectsGetXpnResourcesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsGetXpnResourcesCall) Fields(s ...googleapi.Field) *ProjectsGetXpnResourcesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsGetXpnResourcesCall) IfNoneMatch(entityTag string) *ProjectsGetXpnResourcesCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsGetXpnResourcesCall) Context(ctx context.Context) *ProjectsGetXpnResourcesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsGetXpnResourcesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetXpnResourcesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/getXpnResources")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.getXpnResources" call.
// Exactly one of *ProjectsGetXpnResources or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ProjectsGetXpnResources.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ProjectsGetXpnResourcesCall) Do(opts ...googleapi.CallOption) (*ProjectsGetXpnResources, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ProjectsGetXpnResources{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets service resources (a.k.a service project) associated with this host project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.projects.getXpnResources",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "order_by": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/getXpnResources",
	//   "response": {
	//     "$ref": "ProjectsGetXpnResources"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsGetXpnResourcesCall) Pages(ctx context.Context, f func(*ProjectsGetXpnResources) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.projects.listXpnHosts":

type ProjectsListXpnHostsCall struct {
	s                           *Service
	project                     string
	projectslistxpnhostsrequest *ProjectsListXpnHostsRequest
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// ListXpnHosts: Lists all shared VPC host projects visible to the user
// in an organization. (== suppress_warning http-rest-shadowed ==)
func (r *ProjectsService) ListXpnHosts(project string, projectslistxpnhostsrequest *ProjectsListXpnHostsRequest) *ProjectsListXpnHostsCall {
	c := &ProjectsListXpnHostsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.projectslistxpnhostsrequest = projectslistxpnhostsrequest
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ProjectsListXpnHostsCall) Filter(filter string) *ProjectsListXpnHostsCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ProjectsListXpnHostsCall) MaxResults(maxResults int64) *ProjectsListXpnHostsCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "order_by": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ProjectsListXpnHostsCall) OrderBy(orderBy string) *ProjectsListXpnHostsCall {
	c.urlParams_.Set("order_by", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ProjectsListXpnHostsCall) PageToken(pageToken string) *ProjectsListXpnHostsCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsListXpnHostsCall) Fields(s ...googleapi.Field) *ProjectsListXpnHostsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsListXpnHostsCall) Context(ctx context.Context) *ProjectsListXpnHostsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsListXpnHostsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsListXpnHostsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.projectslistxpnhostsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/listXpnHosts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.listXpnHosts" call.
// Exactly one of *XpnHostList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *XpnHostList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsListXpnHostsCall) Do(opts ...googleapi.CallOption) (*XpnHostList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &XpnHostList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists all shared VPC host projects visible to the user in an organization. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.listXpnHosts",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "order_by": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/listXpnHosts",
	//   "request": {
	//     "$ref": "ProjectsListXpnHostsRequest"
	//   },
	//   "response": {
	//     "$ref": "XpnHostList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsListXpnHostsCall) Pages(ctx context.Context, f func(*XpnHostList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.projects.moveDisk":

type ProjectsMoveDiskCall struct {
	s               *Service
	project         string
	diskmoverequest *DiskMoveRequest
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// MoveDisk: Moves a persistent disk from one zone to another. (==
// suppress_warning http-rest-shadowed ==)
func (r *ProjectsService) MoveDisk(project string, diskmoverequest *DiskMoveRequest) *ProjectsMoveDiskCall {
	c := &ProjectsMoveDiskCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.diskmoverequest = diskmoverequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsMoveDiskCall) RequestId(requestId string) *ProjectsMoveDiskCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsMoveDiskCall) Fields(s ...googleapi.Field) *ProjectsMoveDiskCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsMoveDiskCall) Context(ctx context.Context) *ProjectsMoveDiskCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsMoveDiskCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsMoveDiskCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.diskmoverequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/moveDisk")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.moveDisk" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsMoveDiskCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Moves a persistent disk from one zone to another. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.moveDisk",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/moveDisk",
	//   "request": {
	//     "$ref": "DiskMoveRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.moveInstance":

type ProjectsMoveInstanceCall struct {
	s                   *Service
	project             string
	instancemoverequest *InstanceMoveRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// MoveInstance: Moves an instance and its attached persistent disks
// from one zone to another. (== suppress_warning http-rest-shadowed ==)
func (r *ProjectsService) MoveInstance(project string, instancemoverequest *InstanceMoveRequest) *ProjectsMoveInstanceCall {
	c := &ProjectsMoveInstanceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.instancemoverequest = instancemoverequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsMoveInstanceCall) RequestId(requestId string) *ProjectsMoveInstanceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsMoveInstanceCall) Fields(s ...googleapi.Field) *ProjectsMoveInstanceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsMoveInstanceCall) Context(ctx context.Context) *ProjectsMoveInstanceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsMoveInstanceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsMoveInstanceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancemoverequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/moveInstance")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.moveInstance" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsMoveInstanceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Moves an instance and its attached persistent disks from one zone to another. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.moveInstance",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/moveInstance",
	//   "request": {
	//     "$ref": "InstanceMoveRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.setCommonInstanceMetadata":

type ProjectsSetCommonInstanceMetadataCall struct {
	s          *Service
	project    string
	metadata   *Metadata
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SetCommonInstanceMetadata: Sets metadata common to all instances
// within the specified project using the data included in the request.
// (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/projects/setCommonInstanceMetadata
func (r *ProjectsService) SetCommonInstanceMetadata(project string, metadata *Metadata) *ProjectsSetCommonInstanceMetadataCall {
	c := &ProjectsSetCommonInstanceMetadataCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.metadata = metadata
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsSetCommonInstanceMetadataCall) RequestId(requestId string) *ProjectsSetCommonInstanceMetadataCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsSetCommonInstanceMetadataCall) Fields(s ...googleapi.Field) *ProjectsSetCommonInstanceMetadataCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsSetCommonInstanceMetadataCall) Context(ctx context.Context) *ProjectsSetCommonInstanceMetadataCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsSetCommonInstanceMetadataCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsSetCommonInstanceMetadataCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.metadata)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/setCommonInstanceMetadata")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.setCommonInstanceMetadata" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsSetCommonInstanceMetadataCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets metadata common to all instances within the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.setCommonInstanceMetadata",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/setCommonInstanceMetadata",
	//   "request": {
	//     "$ref": "Metadata"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.setDefaultNetworkTier":

type ProjectsSetDefaultNetworkTierCall struct {
	s                                    *Service
	project                              string
	projectssetdefaultnetworktierrequest *ProjectsSetDefaultNetworkTierRequest
	urlParams_                           gensupport.URLParams
	ctx_                                 context.Context
	header_                              http.Header
}

// SetDefaultNetworkTier: Sets the default network tier of the project.
// The default network tier is used when an
// address/forwardingRule/instance is created without specifying the
// network tier field. (== suppress_warning http-rest-shadowed ==)
func (r *ProjectsService) SetDefaultNetworkTier(project string, projectssetdefaultnetworktierrequest *ProjectsSetDefaultNetworkTierRequest) *ProjectsSetDefaultNetworkTierCall {
	c := &ProjectsSetDefaultNetworkTierCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.projectssetdefaultnetworktierrequest = projectssetdefaultnetworktierrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsSetDefaultNetworkTierCall) RequestId(requestId string) *ProjectsSetDefaultNetworkTierCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsSetDefaultNetworkTierCall) Fields(s ...googleapi.Field) *ProjectsSetDefaultNetworkTierCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsSetDefaultNetworkTierCall) Context(ctx context.Context) *ProjectsSetDefaultNetworkTierCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsSetDefaultNetworkTierCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsSetDefaultNetworkTierCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.projectssetdefaultnetworktierrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/setDefaultNetworkTier")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.setDefaultNetworkTier" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsSetDefaultNetworkTierCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the default network tier of the project. The default network tier is used when an address/forwardingRule/instance is created without specifying the network tier field. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.setDefaultNetworkTier",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/setDefaultNetworkTier",
	//   "request": {
	//     "$ref": "ProjectsSetDefaultNetworkTierRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.projects.setUsageExportBucket":

type ProjectsSetUsageExportBucketCall struct {
	s                   *Service
	project             string
	usageexportlocation *UsageExportLocation
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetUsageExportBucket: Enables the usage export feature and sets the
// usage export bucket where reports are stored. If you provide an empty
// request body using this method, the usage export feature will be
// disabled. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/projects/setUsageExportBucket
func (r *ProjectsService) SetUsageExportBucket(project string, usageexportlocation *UsageExportLocation) *ProjectsSetUsageExportBucketCall {
	c := &ProjectsSetUsageExportBucketCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.usageexportlocation = usageexportlocation
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ProjectsSetUsageExportBucketCall) RequestId(requestId string) *ProjectsSetUsageExportBucketCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsSetUsageExportBucketCall) Fields(s ...googleapi.Field) *ProjectsSetUsageExportBucketCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsSetUsageExportBucketCall) Context(ctx context.Context) *ProjectsSetUsageExportBucketCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsSetUsageExportBucketCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsSetUsageExportBucketCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.usageexportlocation)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/setUsageExportBucket")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.projects.setUsageExportBucket" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsSetUsageExportBucketCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Enables the usage export feature and sets the usage export bucket where reports are stored. If you provide an empty request body using this method, the usage export feature will be disabled. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.projects.setUsageExportBucket",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/setUsageExportBucket",
	//   "request": {
	//     "$ref": "UsageExportLocation"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/devstorage.full_control",
	//     "https://www.googleapis.com/auth/devstorage.read_only",
	//     "https://www.googleapis.com/auth/devstorage.read_write"
	//   ]
	// }

}

// method id "compute.regionAutoscalers.delete":

type RegionAutoscalersDeleteCall struct {
	s          *Service
	project    string
	region     string
	autoscaler string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified autoscaler. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionAutoscalersService) Delete(project string, region string, autoscaler string) *RegionAutoscalersDeleteCall {
	c := &RegionAutoscalersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.autoscaler = autoscaler
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionAutoscalersDeleteCall) RequestId(requestId string) *RegionAutoscalersDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionAutoscalersDeleteCall) Fields(s ...googleapi.Field) *RegionAutoscalersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionAutoscalersDeleteCall) Context(ctx context.Context) *RegionAutoscalersDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionAutoscalersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionAutoscalersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/autoscalers/{autoscaler}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"autoscaler": c.autoscaler,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionAutoscalers.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionAutoscalersDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified autoscaler. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionAutoscalers.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "autoscaler"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/autoscalers/{autoscaler}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionAutoscalers.get":

type RegionAutoscalersGetCall struct {
	s            *Service
	project      string
	region       string
	autoscaler   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified autoscaler. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionAutoscalersService) Get(project string, region string, autoscaler string) *RegionAutoscalersGetCall {
	c := &RegionAutoscalersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.autoscaler = autoscaler
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionAutoscalersGetCall) Fields(s ...googleapi.Field) *RegionAutoscalersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionAutoscalersGetCall) IfNoneMatch(entityTag string) *RegionAutoscalersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionAutoscalersGetCall) Context(ctx context.Context) *RegionAutoscalersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionAutoscalersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionAutoscalersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/autoscalers/{autoscaler}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"autoscaler": c.autoscaler,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionAutoscalers.get" call.
// Exactly one of *Autoscaler or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Autoscaler.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionAutoscalersGetCall) Do(opts ...googleapi.CallOption) (*Autoscaler, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Autoscaler{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified autoscaler. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionAutoscalers.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "autoscaler"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/autoscalers/{autoscaler}",
	//   "response": {
	//     "$ref": "Autoscaler"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionAutoscalers.insert":

type RegionAutoscalersInsertCall struct {
	s          *Service
	project    string
	region     string
	autoscaler *Autoscaler
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates an autoscaler in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionAutoscalersService) Insert(project string, region string, autoscaler *Autoscaler) *RegionAutoscalersInsertCall {
	c := &RegionAutoscalersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.autoscaler = autoscaler
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionAutoscalersInsertCall) RequestId(requestId string) *RegionAutoscalersInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionAutoscalersInsertCall) Fields(s ...googleapi.Field) *RegionAutoscalersInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionAutoscalersInsertCall) Context(ctx context.Context) *RegionAutoscalersInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionAutoscalersInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionAutoscalersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.autoscaler)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionAutoscalers.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionAutoscalersInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an autoscaler in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionAutoscalers.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/autoscalers",
	//   "request": {
	//     "$ref": "Autoscaler"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionAutoscalers.list":

type RegionAutoscalersListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of autoscalers contained within the specified
// region. (== suppress_warning http-rest-shadowed ==)
func (r *RegionAutoscalersService) List(project string, region string) *RegionAutoscalersListCall {
	c := &RegionAutoscalersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionAutoscalersListCall) Filter(filter string) *RegionAutoscalersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionAutoscalersListCall) MaxResults(maxResults int64) *RegionAutoscalersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionAutoscalersListCall) OrderBy(orderBy string) *RegionAutoscalersListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionAutoscalersListCall) PageToken(pageToken string) *RegionAutoscalersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionAutoscalersListCall) Fields(s ...googleapi.Field) *RegionAutoscalersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionAutoscalersListCall) IfNoneMatch(entityTag string) *RegionAutoscalersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionAutoscalersListCall) Context(ctx context.Context) *RegionAutoscalersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionAutoscalersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionAutoscalersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionAutoscalers.list" call.
// Exactly one of *RegionAutoscalerList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RegionAutoscalerList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionAutoscalersListCall) Do(opts ...googleapi.CallOption) (*RegionAutoscalerList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionAutoscalerList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of autoscalers contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionAutoscalers.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/autoscalers",
	//   "response": {
	//     "$ref": "RegionAutoscalerList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionAutoscalersListCall) Pages(ctx context.Context, f func(*RegionAutoscalerList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionAutoscalers.patch":

type RegionAutoscalersPatchCall struct {
	s          *Service
	project    string
	region     string
	autoscaler *Autoscaler
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an autoscaler in the specified project using the data
// included in the request. This method supports PATCH semantics and
// uses the JSON merge patch format and processing rules. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionAutoscalersService) Patch(project string, region string, autoscaler *Autoscaler) *RegionAutoscalersPatchCall {
	c := &RegionAutoscalersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.autoscaler = autoscaler
	return c
}

// Autoscaler sets the optional parameter "autoscaler": Name of the
// autoscaler to patch.
func (c *RegionAutoscalersPatchCall) Autoscaler(autoscaler string) *RegionAutoscalersPatchCall {
	c.urlParams_.Set("autoscaler", autoscaler)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionAutoscalersPatchCall) RequestId(requestId string) *RegionAutoscalersPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionAutoscalersPatchCall) Fields(s ...googleapi.Field) *RegionAutoscalersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionAutoscalersPatchCall) Context(ctx context.Context) *RegionAutoscalersPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionAutoscalersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionAutoscalersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.autoscaler)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionAutoscalers.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionAutoscalersPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an autoscaler in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.regionAutoscalers.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to patch.",
	//       "location": "query",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/autoscalers",
	//   "request": {
	//     "$ref": "Autoscaler"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionAutoscalers.update":

type RegionAutoscalersUpdateCall struct {
	s          *Service
	project    string
	region     string
	autoscaler *Autoscaler
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an autoscaler in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionAutoscalersService) Update(project string, region string, autoscaler *Autoscaler) *RegionAutoscalersUpdateCall {
	c := &RegionAutoscalersUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.autoscaler = autoscaler
	return c
}

// Autoscaler sets the optional parameter "autoscaler": Name of the
// autoscaler to update.
func (c *RegionAutoscalersUpdateCall) Autoscaler(autoscaler string) *RegionAutoscalersUpdateCall {
	c.urlParams_.Set("autoscaler", autoscaler)
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionAutoscalersUpdateCall) RequestId(requestId string) *RegionAutoscalersUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionAutoscalersUpdateCall) Fields(s ...googleapi.Field) *RegionAutoscalersUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionAutoscalersUpdateCall) Context(ctx context.Context) *RegionAutoscalersUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionAutoscalersUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionAutoscalersUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.autoscaler)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/autoscalers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionAutoscalers.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionAutoscalersUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an autoscaler in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.regionAutoscalers.update",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "autoscaler": {
	//       "description": "Name of the autoscaler to update.",
	//       "location": "query",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/autoscalers",
	//   "request": {
	//     "$ref": "Autoscaler"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionBackendServices.delete":

type RegionBackendServicesDeleteCall struct {
	s              *Service
	project        string
	region         string
	backendService string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified regional BackendService resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionBackendServicesService) Delete(project string, region string, backendService string) *RegionBackendServicesDeleteCall {
	c := &RegionBackendServicesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.backendService = backendService
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionBackendServicesDeleteCall) RequestId(requestId string) *RegionBackendServicesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionBackendServicesDeleteCall) Fields(s ...googleapi.Field) *RegionBackendServicesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionBackendServicesDeleteCall) Context(ctx context.Context) *RegionBackendServicesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionBackendServicesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionBackendServicesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionBackendServices.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionBackendServicesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified regional BackendService resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionBackendServices.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/backendServices/{backendService}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionBackendServices.get":

type RegionBackendServicesGetCall struct {
	s              *Service
	project        string
	region         string
	backendService string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified regional BackendService resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionBackendServicesService) Get(project string, region string, backendService string) *RegionBackendServicesGetCall {
	c := &RegionBackendServicesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.backendService = backendService
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionBackendServicesGetCall) Fields(s ...googleapi.Field) *RegionBackendServicesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionBackendServicesGetCall) IfNoneMatch(entityTag string) *RegionBackendServicesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionBackendServicesGetCall) Context(ctx context.Context) *RegionBackendServicesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionBackendServicesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionBackendServicesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionBackendServices.get" call.
// Exactly one of *BackendService or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *BackendService.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionBackendServicesGetCall) Do(opts ...googleapi.CallOption) (*BackendService, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendService{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified regional BackendService resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionBackendServices.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/backendServices/{backendService}",
	//   "response": {
	//     "$ref": "BackendService"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionBackendServices.getHealth":

type RegionBackendServicesGetHealthCall struct {
	s                      *Service
	project                string
	region                 string
	backendService         string
	resourcegroupreference *ResourceGroupReference
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// GetHealth: Gets the most recent health check results for this
// regional BackendService. (== suppress_warning http-rest-shadowed ==)
func (r *RegionBackendServicesService) GetHealth(project string, region string, backendService string, resourcegroupreference *ResourceGroupReference) *RegionBackendServicesGetHealthCall {
	c := &RegionBackendServicesGetHealthCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.backendService = backendService
	c.resourcegroupreference = resourcegroupreference
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionBackendServicesGetHealthCall) Fields(s ...googleapi.Field) *RegionBackendServicesGetHealthCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionBackendServicesGetHealthCall) Context(ctx context.Context) *RegionBackendServicesGetHealthCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionBackendServicesGetHealthCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionBackendServicesGetHealthCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.resourcegroupreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/backendServices/{backendService}/getHealth")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionBackendServices.getHealth" call.
// Exactly one of *BackendServiceGroupHealth or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BackendServiceGroupHealth.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionBackendServicesGetHealthCall) Do(opts ...googleapi.CallOption) (*BackendServiceGroupHealth, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendServiceGroupHealth{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the most recent health check results for this regional BackendService. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionBackendServices.getHealth",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource for which to get health.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/backendServices/{backendService}/getHealth",
	//   "request": {
	//     "$ref": "ResourceGroupReference"
	//   },
	//   "response": {
	//     "$ref": "BackendServiceGroupHealth"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionBackendServices.insert":

type RegionBackendServicesInsertCall struct {
	s              *Service
	project        string
	region         string
	backendservice *BackendService
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a regional BackendService resource in the specified
// project using the data included in the request. There are several
// restrictions and guidelines to keep in mind when creating a regional
// backend service. Read  Restrictions and Guidelines for more
// information. (== suppress_warning http-rest-shadowed ==)
func (r *RegionBackendServicesService) Insert(project string, region string, backendservice *BackendService) *RegionBackendServicesInsertCall {
	c := &RegionBackendServicesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.backendservice = backendservice
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionBackendServicesInsertCall) RequestId(requestId string) *RegionBackendServicesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionBackendServicesInsertCall) Fields(s ...googleapi.Field) *RegionBackendServicesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionBackendServicesInsertCall) Context(ctx context.Context) *RegionBackendServicesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionBackendServicesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionBackendServicesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/backendServices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionBackendServices.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionBackendServicesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a regional BackendService resource in the specified project using the data included in the request. There are several restrictions and guidelines to keep in mind when creating a regional backend service. Read  Restrictions and Guidelines for more information. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionBackendServices.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/backendServices",
	//   "request": {
	//     "$ref": "BackendService"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionBackendServices.list":

type RegionBackendServicesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of regional BackendService resources
// available to the specified project in the given region. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionBackendServicesService) List(project string, region string) *RegionBackendServicesListCall {
	c := &RegionBackendServicesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionBackendServicesListCall) Filter(filter string) *RegionBackendServicesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionBackendServicesListCall) MaxResults(maxResults int64) *RegionBackendServicesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionBackendServicesListCall) OrderBy(orderBy string) *RegionBackendServicesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionBackendServicesListCall) PageToken(pageToken string) *RegionBackendServicesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionBackendServicesListCall) Fields(s ...googleapi.Field) *RegionBackendServicesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionBackendServicesListCall) IfNoneMatch(entityTag string) *RegionBackendServicesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionBackendServicesListCall) Context(ctx context.Context) *RegionBackendServicesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionBackendServicesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionBackendServicesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/backendServices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionBackendServices.list" call.
// Exactly one of *BackendServiceList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BackendServiceList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionBackendServicesListCall) Do(opts ...googleapi.CallOption) (*BackendServiceList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BackendServiceList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of regional BackendService resources available to the specified project in the given region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionBackendServices.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/backendServices",
	//   "response": {
	//     "$ref": "BackendServiceList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionBackendServicesListCall) Pages(ctx context.Context, f func(*BackendServiceList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionBackendServices.patch":

type RegionBackendServicesPatchCall struct {
	s              *Service
	project        string
	region         string
	backendService string
	backendservice *BackendService
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Patch: Updates the specified regional BackendService resource with
// the data included in the request. There are several restrictions and
// guidelines to keep in mind when updating a backend service. Read
// Restrictions and Guidelines for more information. This method
// supports PATCH semantics and uses the JSON merge patch format and
// processing rules. (== suppress_warning http-rest-shadowed ==)
func (r *RegionBackendServicesService) Patch(project string, region string, backendService string, backendservice *BackendService) *RegionBackendServicesPatchCall {
	c := &RegionBackendServicesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.backendService = backendService
	c.backendservice = backendservice
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionBackendServicesPatchCall) RequestId(requestId string) *RegionBackendServicesPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionBackendServicesPatchCall) Fields(s ...googleapi.Field) *RegionBackendServicesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionBackendServicesPatchCall) Context(ctx context.Context) *RegionBackendServicesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionBackendServicesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionBackendServicesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionBackendServices.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionBackendServicesPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified regional BackendService resource with the data included in the request. There are several restrictions and guidelines to keep in mind when updating a backend service. Read  Restrictions and Guidelines for more information. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.regionBackendServices.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/backendServices/{backendService}",
	//   "request": {
	//     "$ref": "BackendService"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionBackendServices.update":

type RegionBackendServicesUpdateCall struct {
	s              *Service
	project        string
	region         string
	backendService string
	backendservice *BackendService
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Update: Updates the specified regional BackendService resource with
// the data included in the request. There are several restrictions and
// guidelines to keep in mind when updating a backend service. Read
// Restrictions and Guidelines for more information. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionBackendServicesService) Update(project string, region string, backendService string, backendservice *BackendService) *RegionBackendServicesUpdateCall {
	c := &RegionBackendServicesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.backendService = backendService
	c.backendservice = backendservice
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionBackendServicesUpdateCall) RequestId(requestId string) *RegionBackendServicesUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionBackendServicesUpdateCall) Fields(s ...googleapi.Field) *RegionBackendServicesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionBackendServicesUpdateCall) Context(ctx context.Context) *RegionBackendServicesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionBackendServicesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionBackendServicesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/backendServices/{backendService}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"backendService": c.backendService,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionBackendServices.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionBackendServicesUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified regional BackendService resource with the data included in the request. There are several restrictions and guidelines to keep in mind when updating a backend service. Read  Restrictions and Guidelines for more information. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.regionBackendServices.update",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "backendService"
	//   ],
	//   "parameters": {
	//     "backendService": {
	//       "description": "Name of the BackendService resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/backendServices/{backendService}",
	//   "request": {
	//     "$ref": "BackendService"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionCommitments.aggregatedList":

type RegionCommitmentsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of commitments. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionCommitmentsService) AggregatedList(project string) *RegionCommitmentsAggregatedListCall {
	c := &RegionCommitmentsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionCommitmentsAggregatedListCall) Filter(filter string) *RegionCommitmentsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionCommitmentsAggregatedListCall) MaxResults(maxResults int64) *RegionCommitmentsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionCommitmentsAggregatedListCall) OrderBy(orderBy string) *RegionCommitmentsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionCommitmentsAggregatedListCall) PageToken(pageToken string) *RegionCommitmentsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionCommitmentsAggregatedListCall) Fields(s ...googleapi.Field) *RegionCommitmentsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionCommitmentsAggregatedListCall) IfNoneMatch(entityTag string) *RegionCommitmentsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionCommitmentsAggregatedListCall) Context(ctx context.Context) *RegionCommitmentsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionCommitmentsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionCommitmentsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/commitments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionCommitments.aggregatedList" call.
// Exactly one of *CommitmentAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CommitmentAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionCommitmentsAggregatedListCall) Do(opts ...googleapi.CallOption) (*CommitmentAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CommitmentAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of commitments. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionCommitments.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/commitments",
	//   "response": {
	//     "$ref": "CommitmentAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionCommitmentsAggregatedListCall) Pages(ctx context.Context, f func(*CommitmentAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionCommitments.get":

type RegionCommitmentsGetCall struct {
	s            *Service
	project      string
	region       string
	commitment   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified commitment resource. Gets a list of
// available commitments by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionCommitmentsService) Get(project string, region string, commitment string) *RegionCommitmentsGetCall {
	c := &RegionCommitmentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.commitment = commitment
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionCommitmentsGetCall) Fields(s ...googleapi.Field) *RegionCommitmentsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionCommitmentsGetCall) IfNoneMatch(entityTag string) *RegionCommitmentsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionCommitmentsGetCall) Context(ctx context.Context) *RegionCommitmentsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionCommitmentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionCommitmentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/commitments/{commitment}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"commitment": c.commitment,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionCommitments.get" call.
// Exactly one of *Commitment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Commitment.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionCommitmentsGetCall) Do(opts ...googleapi.CallOption) (*Commitment, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Commitment{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified commitment resource. Gets a list of available commitments by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionCommitments.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "commitment"
	//   ],
	//   "parameters": {
	//     "commitment": {
	//       "description": "Name of the commitment to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/commitments/{commitment}",
	//   "response": {
	//     "$ref": "Commitment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionCommitments.insert":

type RegionCommitmentsInsertCall struct {
	s          *Service
	project    string
	region     string
	commitment *Commitment
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a commitment in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionCommitmentsService) Insert(project string, region string, commitment *Commitment) *RegionCommitmentsInsertCall {
	c := &RegionCommitmentsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.commitment = commitment
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionCommitmentsInsertCall) RequestId(requestId string) *RegionCommitmentsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionCommitmentsInsertCall) Fields(s ...googleapi.Field) *RegionCommitmentsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionCommitmentsInsertCall) Context(ctx context.Context) *RegionCommitmentsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionCommitmentsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionCommitmentsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.commitment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/commitments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionCommitments.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionCommitmentsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a commitment in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionCommitments.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/commitments",
	//   "request": {
	//     "$ref": "Commitment"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionCommitments.list":

type RegionCommitmentsListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of commitments contained within the specified
// region. (== suppress_warning http-rest-shadowed ==)
func (r *RegionCommitmentsService) List(project string, region string) *RegionCommitmentsListCall {
	c := &RegionCommitmentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionCommitmentsListCall) Filter(filter string) *RegionCommitmentsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionCommitmentsListCall) MaxResults(maxResults int64) *RegionCommitmentsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionCommitmentsListCall) OrderBy(orderBy string) *RegionCommitmentsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionCommitmentsListCall) PageToken(pageToken string) *RegionCommitmentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionCommitmentsListCall) Fields(s ...googleapi.Field) *RegionCommitmentsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionCommitmentsListCall) IfNoneMatch(entityTag string) *RegionCommitmentsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionCommitmentsListCall) Context(ctx context.Context) *RegionCommitmentsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionCommitmentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionCommitmentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/commitments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionCommitments.list" call.
// Exactly one of *CommitmentList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CommitmentList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionCommitmentsListCall) Do(opts ...googleapi.CallOption) (*CommitmentList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CommitmentList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of commitments contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionCommitments.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/commitments",
	//   "response": {
	//     "$ref": "CommitmentList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionCommitmentsListCall) Pages(ctx context.Context, f func(*CommitmentList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionDiskTypes.get":

type RegionDiskTypesGetCall struct {
	s            *Service
	project      string
	region       string
	diskType     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified regional disk type. Gets a list of
// available disk types by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionDiskTypesService) Get(project string, region string, diskType string) *RegionDiskTypesGetCall {
	c := &RegionDiskTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.diskType = diskType
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDiskTypesGetCall) Fields(s ...googleapi.Field) *RegionDiskTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionDiskTypesGetCall) IfNoneMatch(entityTag string) *RegionDiskTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDiskTypesGetCall) Context(ctx context.Context) *RegionDiskTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDiskTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDiskTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/diskTypes/{diskType}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"diskType": c.diskType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDiskTypes.get" call.
// Exactly one of *DiskType or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *DiskType.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDiskTypesGetCall) Do(opts ...googleapi.CallOption) (*DiskType, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DiskType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified regional disk type. Gets a list of available disk types by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionDiskTypes.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "diskType"
	//   ],
	//   "parameters": {
	//     "diskType": {
	//       "description": "Name of the disk type to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/diskTypes/{diskType}",
	//   "response": {
	//     "$ref": "DiskType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionDiskTypes.list":

type RegionDiskTypesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of regional disk types available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *RegionDiskTypesService) List(project string, region string) *RegionDiskTypesListCall {
	c := &RegionDiskTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionDiskTypesListCall) Filter(filter string) *RegionDiskTypesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionDiskTypesListCall) MaxResults(maxResults int64) *RegionDiskTypesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionDiskTypesListCall) OrderBy(orderBy string) *RegionDiskTypesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionDiskTypesListCall) PageToken(pageToken string) *RegionDiskTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDiskTypesListCall) Fields(s ...googleapi.Field) *RegionDiskTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionDiskTypesListCall) IfNoneMatch(entityTag string) *RegionDiskTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDiskTypesListCall) Context(ctx context.Context) *RegionDiskTypesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDiskTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDiskTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/diskTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDiskTypes.list" call.
// Exactly one of *RegionDiskTypeList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RegionDiskTypeList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionDiskTypesListCall) Do(opts ...googleapi.CallOption) (*RegionDiskTypeList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionDiskTypeList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of regional disk types available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionDiskTypes.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/diskTypes",
	//   "response": {
	//     "$ref": "RegionDiskTypeList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionDiskTypesListCall) Pages(ctx context.Context, f func(*RegionDiskTypeList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionDisks.addResourcePolicies":

type RegionDisksAddResourcePoliciesCall struct {
	s                                     *Service
	project                               string
	region                                string
	disk                                  string
	regiondisksaddresourcepoliciesrequest *RegionDisksAddResourcePoliciesRequest
	urlParams_                            gensupport.URLParams
	ctx_                                  context.Context
	header_                               http.Header
}

// AddResourcePolicies: Adds existing resource policies to a regional
// disk. You can only add one policy which will be applied to this disk
// for scheduling snapshot creation. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionDisksService) AddResourcePolicies(project string, region string, disk string, regiondisksaddresourcepoliciesrequest *RegionDisksAddResourcePoliciesRequest) *RegionDisksAddResourcePoliciesCall {
	c := &RegionDisksAddResourcePoliciesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.disk = disk
	c.regiondisksaddresourcepoliciesrequest = regiondisksaddresourcepoliciesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionDisksAddResourcePoliciesCall) RequestId(requestId string) *RegionDisksAddResourcePoliciesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksAddResourcePoliciesCall) Fields(s ...googleapi.Field) *RegionDisksAddResourcePoliciesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksAddResourcePoliciesCall) Context(ctx context.Context) *RegionDisksAddResourcePoliciesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksAddResourcePoliciesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksAddResourcePoliciesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regiondisksaddresourcepoliciesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{disk}/addResourcePolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.addResourcePolicies" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksAddResourcePoliciesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds existing resource policies to a regional disk. You can only add one policy which will be applied to this disk for scheduling snapshot creation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionDisks.addResourcePolicies",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "The disk name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{disk}/addResourcePolicies",
	//   "request": {
	//     "$ref": "RegionDisksAddResourcePoliciesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionDisks.createSnapshot":

type RegionDisksCreateSnapshotCall struct {
	s          *Service
	project    string
	region     string
	disk       string
	snapshot   *Snapshot
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// CreateSnapshot: Creates a snapshot of this regional disk. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) CreateSnapshot(project string, region string, disk string, snapshot *Snapshot) *RegionDisksCreateSnapshotCall {
	c := &RegionDisksCreateSnapshotCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.disk = disk
	c.snapshot = snapshot
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionDisksCreateSnapshotCall) RequestId(requestId string) *RegionDisksCreateSnapshotCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksCreateSnapshotCall) Fields(s ...googleapi.Field) *RegionDisksCreateSnapshotCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksCreateSnapshotCall) Context(ctx context.Context) *RegionDisksCreateSnapshotCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksCreateSnapshotCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksCreateSnapshotCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.snapshot)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{disk}/createSnapshot")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.createSnapshot" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksCreateSnapshotCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a snapshot of this regional disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionDisks.createSnapshot",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "Name of the regional persistent disk to snapshot.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{disk}/createSnapshot",
	//   "request": {
	//     "$ref": "Snapshot"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionDisks.delete":

type RegionDisksDeleteCall struct {
	s          *Service
	project    string
	region     string
	disk       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified regional persistent disk. Deleting a
// regional disk removes all the replicas of its data permanently and is
// irreversible. However, deleting a disk does not delete any snapshots
// previously made from the disk. You must separately delete snapshots.
// (== suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) Delete(project string, region string, disk string) *RegionDisksDeleteCall {
	c := &RegionDisksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.disk = disk
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionDisksDeleteCall) RequestId(requestId string) *RegionDisksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksDeleteCall) Fields(s ...googleapi.Field) *RegionDisksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksDeleteCall) Context(ctx context.Context) *RegionDisksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{disk}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified regional persistent disk. Deleting a regional disk removes all the replicas of its data permanently and is irreversible. However, deleting a disk does not delete any snapshots previously made from the disk. You must separately delete snapshots. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionDisks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "Name of the regional persistent disk to delete.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{disk}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionDisks.get":

type RegionDisksGetCall struct {
	s            *Service
	project      string
	region       string
	disk         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns a specified regional persistent disk. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) Get(project string, region string, disk string) *RegionDisksGetCall {
	c := &RegionDisksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.disk = disk
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksGetCall) Fields(s ...googleapi.Field) *RegionDisksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionDisksGetCall) IfNoneMatch(entityTag string) *RegionDisksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksGetCall) Context(ctx context.Context) *RegionDisksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{disk}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.get" call.
// Exactly one of *Disk or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Disk.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *RegionDisksGetCall) Do(opts ...googleapi.CallOption) (*Disk, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Disk{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns a specified regional persistent disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionDisks.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "Name of the regional persistent disk to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{disk}",
	//   "response": {
	//     "$ref": "Disk"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionDisks.insert":

type RegionDisksInsertCall struct {
	s          *Service
	project    string
	region     string
	disk       *Disk
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a persistent regional disk in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionDisksService) Insert(project string, region string, disk *Disk) *RegionDisksInsertCall {
	c := &RegionDisksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.disk = disk
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionDisksInsertCall) RequestId(requestId string) *RegionDisksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// SourceImage sets the optional parameter "sourceImage": Source image
// to restore onto a disk.
func (c *RegionDisksInsertCall) SourceImage(sourceImage string) *RegionDisksInsertCall {
	c.urlParams_.Set("sourceImage", sourceImage)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksInsertCall) Fields(s ...googleapi.Field) *RegionDisksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksInsertCall) Context(ctx context.Context) *RegionDisksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.disk)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a persistent regional disk in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionDisks.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sourceImage": {
	//       "description": "Optional. Source image to restore onto a disk.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks",
	//   "request": {
	//     "$ref": "Disk"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionDisks.list":

type RegionDisksListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of persistent disks contained within the
// specified region. (== suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) List(project string, region string) *RegionDisksListCall {
	c := &RegionDisksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionDisksListCall) Filter(filter string) *RegionDisksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionDisksListCall) MaxResults(maxResults int64) *RegionDisksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionDisksListCall) OrderBy(orderBy string) *RegionDisksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionDisksListCall) PageToken(pageToken string) *RegionDisksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksListCall) Fields(s ...googleapi.Field) *RegionDisksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionDisksListCall) IfNoneMatch(entityTag string) *RegionDisksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksListCall) Context(ctx context.Context) *RegionDisksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.list" call.
// Exactly one of *DiskList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *DiskList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksListCall) Do(opts ...googleapi.CallOption) (*DiskList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DiskList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of persistent disks contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionDisks.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks",
	//   "response": {
	//     "$ref": "DiskList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionDisksListCall) Pages(ctx context.Context, f func(*DiskList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionDisks.removeResourcePolicies":

type RegionDisksRemoveResourcePoliciesCall struct {
	s                                        *Service
	project                                  string
	region                                   string
	disk                                     string
	regiondisksremoveresourcepoliciesrequest *RegionDisksRemoveResourcePoliciesRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// RemoveResourcePolicies: Removes resource policies from a regional
// disk. (== suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) RemoveResourcePolicies(project string, region string, disk string, regiondisksremoveresourcepoliciesrequest *RegionDisksRemoveResourcePoliciesRequest) *RegionDisksRemoveResourcePoliciesCall {
	c := &RegionDisksRemoveResourcePoliciesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.disk = disk
	c.regiondisksremoveresourcepoliciesrequest = regiondisksremoveresourcepoliciesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionDisksRemoveResourcePoliciesCall) RequestId(requestId string) *RegionDisksRemoveResourcePoliciesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksRemoveResourcePoliciesCall) Fields(s ...googleapi.Field) *RegionDisksRemoveResourcePoliciesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksRemoveResourcePoliciesCall) Context(ctx context.Context) *RegionDisksRemoveResourcePoliciesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksRemoveResourcePoliciesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksRemoveResourcePoliciesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regiondisksremoveresourcepoliciesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{disk}/removeResourcePolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.removeResourcePolicies" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksRemoveResourcePoliciesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Removes resource policies from a regional disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionDisks.removeResourcePolicies",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "The disk name for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{disk}/removeResourcePolicies",
	//   "request": {
	//     "$ref": "RegionDisksRemoveResourcePoliciesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionDisks.resize":

type RegionDisksResizeCall struct {
	s                        *Service
	project                  string
	region                   string
	disk                     string
	regiondisksresizerequest *RegionDisksResizeRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// Resize: Resizes the specified regional persistent disk. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) Resize(project string, region string, disk string, regiondisksresizerequest *RegionDisksResizeRequest) *RegionDisksResizeCall {
	c := &RegionDisksResizeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.disk = disk
	c.regiondisksresizerequest = regiondisksresizerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionDisksResizeCall) RequestId(requestId string) *RegionDisksResizeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksResizeCall) Fields(s ...googleapi.Field) *RegionDisksResizeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksResizeCall) Context(ctx context.Context) *RegionDisksResizeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksResizeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksResizeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regiondisksresizerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{disk}/resize")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"disk":    c.disk,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.resize" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksResizeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Resizes the specified regional persistent disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionDisks.resize",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "disk"
	//   ],
	//   "parameters": {
	//     "disk": {
	//       "description": "Name of the regional persistent disk.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "The project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{disk}/resize",
	//   "request": {
	//     "$ref": "RegionDisksResizeRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionDisks.setLabels":

type RegionDisksSetLabelsCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	regionsetlabelsrequest *RegionSetLabelsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetLabels: Sets the labels on the target regional disk. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) SetLabels(project string, region string, resource string, regionsetlabelsrequest *RegionSetLabelsRequest) *RegionDisksSetLabelsCall {
	c := &RegionDisksSetLabelsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.regionsetlabelsrequest = regionsetlabelsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionDisksSetLabelsCall) RequestId(requestId string) *RegionDisksSetLabelsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksSetLabelsCall) Fields(s ...googleapi.Field) *RegionDisksSetLabelsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksSetLabelsCall) Context(ctx context.Context) *RegionDisksSetLabelsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksSetLabelsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksSetLabelsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regionsetlabelsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{resource}/setLabels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.setLabels" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionDisksSetLabelsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the labels on the target regional disk. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionDisks.setLabels",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{resource}/setLabels",
	//   "request": {
	//     "$ref": "RegionSetLabelsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionDisks.testIamPermissions":

type RegionDisksTestIamPermissionsCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *RegionDisksService) TestIamPermissions(project string, region string, resource string, testpermissionsrequest *TestPermissionsRequest) *RegionDisksTestIamPermissionsCall {
	c := &RegionDisksTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionDisksTestIamPermissionsCall) Fields(s ...googleapi.Field) *RegionDisksTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionDisksTestIamPermissionsCall) Context(ctx context.Context) *RegionDisksTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionDisksTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionDisksTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/disks/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionDisks.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionDisksTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionDisks.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/disks/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionHealthChecks.delete":

type RegionHealthChecksDeleteCall struct {
	s           *Service
	project     string
	region      string
	healthCheck string
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Delete: Deletes the specified HealthCheck resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionHealthChecksService) Delete(project string, region string, healthCheck string) *RegionHealthChecksDeleteCall {
	c := &RegionHealthChecksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.healthCheck = healthCheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionHealthChecksDeleteCall) RequestId(requestId string) *RegionHealthChecksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionHealthChecksDeleteCall) Fields(s ...googleapi.Field) *RegionHealthChecksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionHealthChecksDeleteCall) Context(ctx context.Context) *RegionHealthChecksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionHealthChecksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionHealthChecksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"region":      c.region,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionHealthChecks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionHealthChecksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified HealthCheck resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionHealthChecks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/healthChecks/{healthCheck}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionHealthChecks.get":

type RegionHealthChecksGetCall struct {
	s            *Service
	project      string
	region       string
	healthCheck  string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified HealthCheck resource. Gets a list of
// available health checks by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionHealthChecksService) Get(project string, region string, healthCheck string) *RegionHealthChecksGetCall {
	c := &RegionHealthChecksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.healthCheck = healthCheck
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionHealthChecksGetCall) Fields(s ...googleapi.Field) *RegionHealthChecksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionHealthChecksGetCall) IfNoneMatch(entityTag string) *RegionHealthChecksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionHealthChecksGetCall) Context(ctx context.Context) *RegionHealthChecksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionHealthChecksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionHealthChecksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"region":      c.region,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionHealthChecks.get" call.
// Exactly one of *HealthCheck or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *HealthCheck.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionHealthChecksGetCall) Do(opts ...googleapi.CallOption) (*HealthCheck, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HealthCheck{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified HealthCheck resource. Gets a list of available health checks by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionHealthChecks.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/healthChecks/{healthCheck}",
	//   "response": {
	//     "$ref": "HealthCheck"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionHealthChecks.insert":

type RegionHealthChecksInsertCall struct {
	s           *Service
	project     string
	region      string
	healthcheck *HealthCheck
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Insert: Creates a HealthCheck resource in the specified project using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionHealthChecksService) Insert(project string, region string, healthcheck *HealthCheck) *RegionHealthChecksInsertCall {
	c := &RegionHealthChecksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.healthcheck = healthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionHealthChecksInsertCall) RequestId(requestId string) *RegionHealthChecksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionHealthChecksInsertCall) Fields(s ...googleapi.Field) *RegionHealthChecksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionHealthChecksInsertCall) Context(ctx context.Context) *RegionHealthChecksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionHealthChecksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionHealthChecksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.healthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/healthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionHealthChecks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionHealthChecksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a HealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionHealthChecks.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/healthChecks",
	//   "request": {
	//     "$ref": "HealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionHealthChecks.list":

type RegionHealthChecksListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of HealthCheck resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *RegionHealthChecksService) List(project string, region string) *RegionHealthChecksListCall {
	c := &RegionHealthChecksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionHealthChecksListCall) Filter(filter string) *RegionHealthChecksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionHealthChecksListCall) MaxResults(maxResults int64) *RegionHealthChecksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionHealthChecksListCall) OrderBy(orderBy string) *RegionHealthChecksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionHealthChecksListCall) PageToken(pageToken string) *RegionHealthChecksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionHealthChecksListCall) Fields(s ...googleapi.Field) *RegionHealthChecksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionHealthChecksListCall) IfNoneMatch(entityTag string) *RegionHealthChecksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionHealthChecksListCall) Context(ctx context.Context) *RegionHealthChecksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionHealthChecksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionHealthChecksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/healthChecks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionHealthChecks.list" call.
// Exactly one of *HealthCheckList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *HealthCheckList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionHealthChecksListCall) Do(opts ...googleapi.CallOption) (*HealthCheckList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &HealthCheckList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of HealthCheck resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionHealthChecks.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/healthChecks",
	//   "response": {
	//     "$ref": "HealthCheckList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionHealthChecksListCall) Pages(ctx context.Context, f func(*HealthCheckList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionHealthChecks.patch":

type RegionHealthChecksPatchCall struct {
	s           *Service
	project     string
	region      string
	healthCheck string
	healthcheck *HealthCheck
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Patch: Updates a HealthCheck resource in the specified project using
// the data included in the request. This method supports PATCH
// semantics and uses the JSON merge patch format and processing rules.
// (== suppress_warning http-rest-shadowed ==)
func (r *RegionHealthChecksService) Patch(project string, region string, healthCheck string, healthcheck *HealthCheck) *RegionHealthChecksPatchCall {
	c := &RegionHealthChecksPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.healthCheck = healthCheck
	c.healthcheck = healthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionHealthChecksPatchCall) RequestId(requestId string) *RegionHealthChecksPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionHealthChecksPatchCall) Fields(s ...googleapi.Field) *RegionHealthChecksPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionHealthChecksPatchCall) Context(ctx context.Context) *RegionHealthChecksPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionHealthChecksPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionHealthChecksPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.healthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"region":      c.region,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionHealthChecks.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionHealthChecksPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.regionHealthChecks.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/healthChecks/{healthCheck}",
	//   "request": {
	//     "$ref": "HealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionHealthChecks.update":

type RegionHealthChecksUpdateCall struct {
	s           *Service
	project     string
	region      string
	healthCheck string
	healthcheck *HealthCheck
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Update: Updates a HealthCheck resource in the specified project using
// the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionHealthChecksService) Update(project string, region string, healthCheck string, healthcheck *HealthCheck) *RegionHealthChecksUpdateCall {
	c := &RegionHealthChecksUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.healthCheck = healthCheck
	c.healthcheck = healthcheck
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionHealthChecksUpdateCall) RequestId(requestId string) *RegionHealthChecksUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionHealthChecksUpdateCall) Fields(s ...googleapi.Field) *RegionHealthChecksUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionHealthChecksUpdateCall) Context(ctx context.Context) *RegionHealthChecksUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionHealthChecksUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionHealthChecksUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.healthcheck)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/healthChecks/{healthCheck}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"region":      c.region,
		"healthCheck": c.healthCheck,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionHealthChecks.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionHealthChecksUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a HealthCheck resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.regionHealthChecks.update",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "healthCheck"
	//   ],
	//   "parameters": {
	//     "healthCheck": {
	//       "description": "Name of the HealthCheck resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/healthChecks/{healthCheck}",
	//   "request": {
	//     "$ref": "HealthCheck"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.abandonInstances":

type RegionInstanceGroupManagersAbandonInstancesCall struct {
	s                                                  *Service
	project                                            string
	region                                             string
	instanceGroupManager                               string
	regioninstancegroupmanagersabandoninstancesrequest *RegionInstanceGroupManagersAbandonInstancesRequest
	urlParams_                                         gensupport.URLParams
	ctx_                                               context.Context
	header_                                            http.Header
}

// AbandonInstances: Flags the specified instances to be immediately
// removed from the managed instance group. Abandoning an instance does
// not delete the instance, but it does remove the instance from any
// target pools that are applied by the managed instance group. This
// method reduces the targetSize of the managed instance group by the
// number of instances that you abandon. This operation is marked as
// DONE when the action is scheduled even if the instances have not yet
// been removed from the group. You must separately verify the status of
// the abandoning action with the listmanagedinstances method.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or
// deleted.
//
// You can specify a maximum of 1000 instances with this method per
// request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) AbandonInstances(project string, region string, instanceGroupManager string, regioninstancegroupmanagersabandoninstancesrequest *RegionInstanceGroupManagersAbandonInstancesRequest) *RegionInstanceGroupManagersAbandonInstancesCall {
	c := &RegionInstanceGroupManagersAbandonInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	c.regioninstancegroupmanagersabandoninstancesrequest = regioninstancegroupmanagersabandoninstancesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersAbandonInstancesCall) RequestId(requestId string) *RegionInstanceGroupManagersAbandonInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersAbandonInstancesCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersAbandonInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersAbandonInstancesCall) Context(ctx context.Context) *RegionInstanceGroupManagersAbandonInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersAbandonInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersAbandonInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regioninstancegroupmanagersabandoninstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/abandonInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.abandonInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersAbandonInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Flags the specified instances to be immediately removed from the managed instance group. Abandoning an instance does not delete the instance, but it does remove the instance from any target pools that are applied by the managed instance group. This method reduces the targetSize of the managed instance group by the number of instances that you abandon. This operation is marked as DONE when the action is scheduled even if the instances have not yet been removed from the group. You must separately verify the status of the abandoning action with the listmanagedinstances method.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.\n\nYou can specify a maximum of 1000 instances with this method per request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.abandonInstances",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "Name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/abandonInstances",
	//   "request": {
	//     "$ref": "RegionInstanceGroupManagersAbandonInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.delete":

type RegionInstanceGroupManagersDeleteCall struct {
	s                    *Service
	project              string
	region               string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Delete: Deletes the specified managed instance group and all of the
// instances in that group. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) Delete(project string, region string, instanceGroupManager string) *RegionInstanceGroupManagersDeleteCall {
	c := &RegionInstanceGroupManagersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersDeleteCall) RequestId(requestId string) *RegionInstanceGroupManagersDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersDeleteCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersDeleteCall) Context(ctx context.Context) *RegionInstanceGroupManagersDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified managed instance group and all of the instances in that group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionInstanceGroupManagers.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "Name of the managed instance group to delete.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.deleteInstances":

type RegionInstanceGroupManagersDeleteInstancesCall struct {
	s                                                 *Service
	project                                           string
	region                                            string
	instanceGroupManager                              string
	regioninstancegroupmanagersdeleteinstancesrequest *RegionInstanceGroupManagersDeleteInstancesRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// DeleteInstances: Flags the specified instances in the managed
// instance group to be immediately deleted. The instances are also
// removed from any target pools of which they were a member. This
// method reduces the targetSize of the managed instance group by the
// number of instances that you delete. The deleteInstances operation is
// marked DONE if the deleteInstances request is successful. The
// underlying actions take additional time. You must separately verify
// the status of the deleting action with the listmanagedinstances
// method.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or
// deleted.
//
// You can specify a maximum of 1000 instances with this method per
// request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) DeleteInstances(project string, region string, instanceGroupManager string, regioninstancegroupmanagersdeleteinstancesrequest *RegionInstanceGroupManagersDeleteInstancesRequest) *RegionInstanceGroupManagersDeleteInstancesCall {
	c := &RegionInstanceGroupManagersDeleteInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	c.regioninstancegroupmanagersdeleteinstancesrequest = regioninstancegroupmanagersdeleteinstancesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersDeleteInstancesCall) RequestId(requestId string) *RegionInstanceGroupManagersDeleteInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersDeleteInstancesCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersDeleteInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersDeleteInstancesCall) Context(ctx context.Context) *RegionInstanceGroupManagersDeleteInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersDeleteInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersDeleteInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regioninstancegroupmanagersdeleteinstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/deleteInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.deleteInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersDeleteInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Flags the specified instances in the managed instance group to be immediately deleted. The instances are also removed from any target pools of which they were a member. This method reduces the targetSize of the managed instance group by the number of instances that you delete. The deleteInstances operation is marked DONE if the deleteInstances request is successful. The underlying actions take additional time. You must separately verify the status of the deleting action with the listmanagedinstances method.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.\n\nYou can specify a maximum of 1000 instances with this method per request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.deleteInstances",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "Name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/deleteInstances",
	//   "request": {
	//     "$ref": "RegionInstanceGroupManagersDeleteInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.get":

type RegionInstanceGroupManagersGetCall struct {
	s                    *Service
	project              string
	region               string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ifNoneMatch_         string
	ctx_                 context.Context
	header_              http.Header
}

// Get: Returns all of the details about the specified managed instance
// group. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) Get(project string, region string, instanceGroupManager string) *RegionInstanceGroupManagersGetCall {
	c := &RegionInstanceGroupManagersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersGetCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionInstanceGroupManagersGetCall) IfNoneMatch(entityTag string) *RegionInstanceGroupManagersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersGetCall) Context(ctx context.Context) *RegionInstanceGroupManagersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.get" call.
// Exactly one of *InstanceGroupManager or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InstanceGroupManager.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersGetCall) Do(opts ...googleapi.CallOption) (*InstanceGroupManager, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroupManager{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns all of the details about the specified managed instance group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionInstanceGroupManagers.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "Name of the managed instance group to return.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}",
	//   "response": {
	//     "$ref": "InstanceGroupManager"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.insert":

type RegionInstanceGroupManagersInsertCall struct {
	s                    *Service
	project              string
	region               string
	instancegroupmanager *InstanceGroupManager
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Insert: Creates a managed instance group using the information that
// you specify in the request. After the group is created, instances in
// the group are created using the specified instance template. This
// operation is marked as DONE when the group is created even if the
// instances in the group have not yet been created. You must separately
// verify the status of the individual instances with the
// listmanagedinstances method.
//
// A regional managed instance group can contain up to 2000 instances.
// (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) Insert(project string, region string, instancegroupmanager *InstanceGroupManager) *RegionInstanceGroupManagersInsertCall {
	c := &RegionInstanceGroupManagersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instancegroupmanager = instancegroupmanager
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersInsertCall) RequestId(requestId string) *RegionInstanceGroupManagersInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersInsertCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersInsertCall) Context(ctx context.Context) *RegionInstanceGroupManagersInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanager)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a managed instance group using the information that you specify in the request. After the group is created, instances in the group are created using the specified instance template. This operation is marked as DONE when the group is created even if the instances in the group have not yet been created. You must separately verify the status of the individual instances with the listmanagedinstances method.\n\nA regional managed instance group can contain up to 2000 instances. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers",
	//   "request": {
	//     "$ref": "InstanceGroupManager"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.list":

type RegionInstanceGroupManagersListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of managed instance groups that are
// contained within the specified region. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) List(project string, region string) *RegionInstanceGroupManagersListCall {
	c := &RegionInstanceGroupManagersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionInstanceGroupManagersListCall) Filter(filter string) *RegionInstanceGroupManagersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionInstanceGroupManagersListCall) MaxResults(maxResults int64) *RegionInstanceGroupManagersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionInstanceGroupManagersListCall) OrderBy(orderBy string) *RegionInstanceGroupManagersListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionInstanceGroupManagersListCall) PageToken(pageToken string) *RegionInstanceGroupManagersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersListCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionInstanceGroupManagersListCall) IfNoneMatch(entityTag string) *RegionInstanceGroupManagersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersListCall) Context(ctx context.Context) *RegionInstanceGroupManagersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.list" call.
// Exactly one of *RegionInstanceGroupManagerList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *RegionInstanceGroupManagerList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersListCall) Do(opts ...googleapi.CallOption) (*RegionInstanceGroupManagerList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionInstanceGroupManagerList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of managed instance groups that are contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionInstanceGroupManagers.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers",
	//   "response": {
	//     "$ref": "RegionInstanceGroupManagerList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionInstanceGroupManagersListCall) Pages(ctx context.Context, f func(*RegionInstanceGroupManagerList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionInstanceGroupManagers.listManagedInstances":

type RegionInstanceGroupManagersListManagedInstancesCall struct {
	s                    *Service
	project              string
	region               string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// ListManagedInstances: Lists the instances in the managed instance
// group and instances that are scheduled to be created. The list
// includes any current actions that the group has scheduled for its
// instances. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) ListManagedInstances(project string, region string, instanceGroupManager string) *RegionInstanceGroupManagersListManagedInstancesCall {
	c := &RegionInstanceGroupManagersListManagedInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionInstanceGroupManagersListManagedInstancesCall) Filter(filter string) *RegionInstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionInstanceGroupManagersListManagedInstancesCall) MaxResults(maxResults int64) *RegionInstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "order_by": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionInstanceGroupManagersListManagedInstancesCall) OrderBy(orderBy string) *RegionInstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("order_by", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionInstanceGroupManagersListManagedInstancesCall) PageToken(pageToken string) *RegionInstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersListManagedInstancesCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersListManagedInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersListManagedInstancesCall) Context(ctx context.Context) *RegionInstanceGroupManagersListManagedInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersListManagedInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersListManagedInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/listManagedInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.listManagedInstances" call.
// Exactly one of *RegionInstanceGroupManagersListInstancesResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *RegionInstanceGroupManagersListInstancesResponse.ServerResponse.Heade
// r or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *RegionInstanceGroupManagersListManagedInstancesCall) Do(opts ...googleapi.CallOption) (*RegionInstanceGroupManagersListInstancesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionInstanceGroupManagersListInstancesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists the instances in the managed instance group and instances that are scheduled to be created. The list includes any current actions that the group has scheduled for its instances. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.listManagedInstances",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "order_by": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/listManagedInstances",
	//   "response": {
	//     "$ref": "RegionInstanceGroupManagersListInstancesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.patch":

type RegionInstanceGroupManagersPatchCall struct {
	s                    *Service
	project              string
	region               string
	instanceGroupManager string
	instancegroupmanager *InstanceGroupManager
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Patch: Updates a managed instance group using the information that
// you specify in the request. This operation is marked as DONE when the
// group is patched even if the instances in the group are still in the
// process of being patched. You must separately verify the status of
// the individual instances with the listmanagedinstances method. This
// method supports PATCH semantics and uses the JSON merge patch format
// and processing rules. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) Patch(project string, region string, instanceGroupManager string, instancegroupmanager *InstanceGroupManager) *RegionInstanceGroupManagersPatchCall {
	c := &RegionInstanceGroupManagersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	c.instancegroupmanager = instancegroupmanager
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersPatchCall) RequestId(requestId string) *RegionInstanceGroupManagersPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersPatchCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersPatchCall) Context(ctx context.Context) *RegionInstanceGroupManagersPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancegroupmanager)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a managed instance group using the information that you specify in the request. This operation is marked as DONE when the group is patched even if the instances in the group are still in the process of being patched. You must separately verify the status of the individual instances with the listmanagedinstances method. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.regionInstanceGroupManagers.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the instance group manager.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}",
	//   "request": {
	//     "$ref": "InstanceGroupManager"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.recreateInstances":

type RegionInstanceGroupManagersRecreateInstancesCall struct {
	s                                          *Service
	project                                    string
	region                                     string
	instanceGroupManager                       string
	regioninstancegroupmanagersrecreaterequest *RegionInstanceGroupManagersRecreateRequest
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// RecreateInstances: Flags the specified instances in the managed
// instance group to be immediately recreated. The instances are deleted
// and recreated using the current instance template for the managed
// instance group. This operation is marked as DONE when the flag is set
// even if the instances have not yet been recreated. You must
// separately verify the status of the recreating action with the
// listmanagedinstances method.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or
// deleted.
//
// You can specify a maximum of 1000 instances with this method per
// request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) RecreateInstances(project string, region string, instanceGroupManager string, regioninstancegroupmanagersrecreaterequest *RegionInstanceGroupManagersRecreateRequest) *RegionInstanceGroupManagersRecreateInstancesCall {
	c := &RegionInstanceGroupManagersRecreateInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	c.regioninstancegroupmanagersrecreaterequest = regioninstancegroupmanagersrecreaterequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersRecreateInstancesCall) RequestId(requestId string) *RegionInstanceGroupManagersRecreateInstancesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersRecreateInstancesCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersRecreateInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersRecreateInstancesCall) Context(ctx context.Context) *RegionInstanceGroupManagersRecreateInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersRecreateInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersRecreateInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regioninstancegroupmanagersrecreaterequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/recreateInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.recreateInstances" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersRecreateInstancesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Flags the specified instances in the managed instance group to be immediately recreated. The instances are deleted and recreated using the current instance template for the managed instance group. This operation is marked as DONE when the flag is set even if the instances have not yet been recreated. You must separately verify the status of the recreating action with the listmanagedinstances method.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.\n\nYou can specify a maximum of 1000 instances with this method per request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.recreateInstances",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "Name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/recreateInstances",
	//   "request": {
	//     "$ref": "RegionInstanceGroupManagersRecreateRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.resize":

type RegionInstanceGroupManagersResizeCall struct {
	s                    *Service
	project              string
	region               string
	instanceGroupManager string
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Resize: Changes the intended size of the managed instance group. If
// you increase the size, the group creates new instances using the
// current instance template. If you decrease the size, the group
// deletes one or more instances.
//
// The resize operation is marked DONE if the resize request is
// successful. The underlying actions take additional time. You must
// separately verify the status of the creating or deleting actions with
// the listmanagedinstances method.
//
// If the group is part of a backend service that has enabled connection
// draining, it can take up to 60 seconds after the connection draining
// duration has elapsed before the VM instance is removed or deleted.
// (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) Resize(project string, region string, instanceGroupManager string, size int64) *RegionInstanceGroupManagersResizeCall {
	c := &RegionInstanceGroupManagersResizeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	c.urlParams_.Set("size", fmt.Sprint(size))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersResizeCall) RequestId(requestId string) *RegionInstanceGroupManagersResizeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersResizeCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersResizeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersResizeCall) Context(ctx context.Context) *RegionInstanceGroupManagersResizeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersResizeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersResizeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/resize")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.resize" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersResizeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the intended size of the managed instance group. If you increase the size, the group creates new instances using the current instance template. If you decrease the size, the group deletes one or more instances.\n\nThe resize operation is marked DONE if the resize request is successful. The underlying actions take additional time. You must separately verify the status of the creating or deleting actions with the listmanagedinstances method.\n\nIf the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.resize",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager",
	//     "size"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "Name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "size": {
	//       "description": "Number of instances that should exist in this instance group manager.",
	//       "format": "int32",
	//       "location": "query",
	//       "minimum": "0",
	//       "required": true,
	//       "type": "integer"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/resize",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.setInstanceTemplate":

type RegionInstanceGroupManagersSetInstanceTemplateCall struct {
	s                                             *Service
	project                                       string
	region                                        string
	instanceGroupManager                          string
	regioninstancegroupmanagerssettemplaterequest *RegionInstanceGroupManagersSetTemplateRequest
	urlParams_                                    gensupport.URLParams
	ctx_                                          context.Context
	header_                                       http.Header
}

// SetInstanceTemplate: Sets the instance template to use when creating
// new instances or recreating instances in this group. Existing
// instances are not affected. (== suppress_warning http-rest-shadowed
// ==)
func (r *RegionInstanceGroupManagersService) SetInstanceTemplate(project string, region string, instanceGroupManager string, regioninstancegroupmanagerssettemplaterequest *RegionInstanceGroupManagersSetTemplateRequest) *RegionInstanceGroupManagersSetInstanceTemplateCall {
	c := &RegionInstanceGroupManagersSetInstanceTemplateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	c.regioninstancegroupmanagerssettemplaterequest = regioninstancegroupmanagerssettemplaterequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersSetInstanceTemplateCall) RequestId(requestId string) *RegionInstanceGroupManagersSetInstanceTemplateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersSetInstanceTemplateCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersSetInstanceTemplateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersSetInstanceTemplateCall) Context(ctx context.Context) *RegionInstanceGroupManagersSetInstanceTemplateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersSetInstanceTemplateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersSetInstanceTemplateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regioninstancegroupmanagerssettemplaterequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/setInstanceTemplate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.setInstanceTemplate" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersSetInstanceTemplateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the instance template to use when creating new instances or recreating instances in this group. Existing instances are not affected. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.setInstanceTemplate",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "The name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/setInstanceTemplate",
	//   "request": {
	//     "$ref": "RegionInstanceGroupManagersSetTemplateRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroupManagers.setTargetPools":

type RegionInstanceGroupManagersSetTargetPoolsCall struct {
	s                                                *Service
	project                                          string
	region                                           string
	instanceGroupManager                             string
	regioninstancegroupmanagerssettargetpoolsrequest *RegionInstanceGroupManagersSetTargetPoolsRequest
	urlParams_                                       gensupport.URLParams
	ctx_                                             context.Context
	header_                                          http.Header
}

// SetTargetPools: Modifies the target pools to which all new instances
// in this group are assigned. Existing instances in the group are not
// affected. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupManagersService) SetTargetPools(project string, region string, instanceGroupManager string, regioninstancegroupmanagerssettargetpoolsrequest *RegionInstanceGroupManagersSetTargetPoolsRequest) *RegionInstanceGroupManagersSetTargetPoolsCall {
	c := &RegionInstanceGroupManagersSetTargetPoolsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroupManager = instanceGroupManager
	c.regioninstancegroupmanagerssettargetpoolsrequest = regioninstancegroupmanagerssettargetpoolsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupManagersSetTargetPoolsCall) RequestId(requestId string) *RegionInstanceGroupManagersSetTargetPoolsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupManagersSetTargetPoolsCall) Fields(s ...googleapi.Field) *RegionInstanceGroupManagersSetTargetPoolsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupManagersSetTargetPoolsCall) Context(ctx context.Context) *RegionInstanceGroupManagersSetTargetPoolsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupManagersSetTargetPoolsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupManagersSetTargetPoolsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regioninstancegroupmanagerssettargetpoolsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/setTargetPools")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":              c.project,
		"region":               c.region,
		"instanceGroupManager": c.instanceGroupManager,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroupManagers.setTargetPools" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupManagersSetTargetPoolsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Modifies the target pools to which all new instances in this group are assigned. Existing instances in the group are not affected. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroupManagers.setTargetPools",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroupManager"
	//   ],
	//   "parameters": {
	//     "instanceGroupManager": {
	//       "description": "Name of the managed instance group.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroupManagers/{instanceGroupManager}/setTargetPools",
	//   "request": {
	//     "$ref": "RegionInstanceGroupManagersSetTargetPoolsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionInstanceGroups.get":

type RegionInstanceGroupsGetCall struct {
	s             *Service
	project       string
	region        string
	instanceGroup string
	urlParams_    gensupport.URLParams
	ifNoneMatch_  string
	ctx_          context.Context
	header_       http.Header
}

// Get: Returns the specified instance group resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupsService) Get(project string, region string, instanceGroup string) *RegionInstanceGroupsGetCall {
	c := &RegionInstanceGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroup = instanceGroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupsGetCall) Fields(s ...googleapi.Field) *RegionInstanceGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionInstanceGroupsGetCall) IfNoneMatch(entityTag string) *RegionInstanceGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupsGetCall) Context(ctx context.Context) *RegionInstanceGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroups/{instanceGroup}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"region":        c.region,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroups.get" call.
// Exactly one of *InstanceGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InstanceGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionInstanceGroupsGetCall) Do(opts ...googleapi.CallOption) (*InstanceGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InstanceGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified instance group resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionInstanceGroups.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "instanceGroup": {
	//       "description": "Name of the instance group resource to return.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroups/{instanceGroup}",
	//   "response": {
	//     "$ref": "InstanceGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionInstanceGroups.list":

type RegionInstanceGroupsListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of instance group resources contained within
// the specified region. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupsService) List(project string, region string) *RegionInstanceGroupsListCall {
	c := &RegionInstanceGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionInstanceGroupsListCall) Filter(filter string) *RegionInstanceGroupsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionInstanceGroupsListCall) MaxResults(maxResults int64) *RegionInstanceGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionInstanceGroupsListCall) OrderBy(orderBy string) *RegionInstanceGroupsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionInstanceGroupsListCall) PageToken(pageToken string) *RegionInstanceGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupsListCall) Fields(s ...googleapi.Field) *RegionInstanceGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionInstanceGroupsListCall) IfNoneMatch(entityTag string) *RegionInstanceGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupsListCall) Context(ctx context.Context) *RegionInstanceGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroups.list" call.
// Exactly one of *RegionInstanceGroupList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RegionInstanceGroupList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionInstanceGroupsListCall) Do(opts ...googleapi.CallOption) (*RegionInstanceGroupList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionInstanceGroupList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of instance group resources contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionInstanceGroups.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroups",
	//   "response": {
	//     "$ref": "RegionInstanceGroupList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionInstanceGroupsListCall) Pages(ctx context.Context, f func(*RegionInstanceGroupList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionInstanceGroups.listInstances":

type RegionInstanceGroupsListInstancesCall struct {
	s                                        *Service
	project                                  string
	region                                   string
	instanceGroup                            string
	regioninstancegroupslistinstancesrequest *RegionInstanceGroupsListInstancesRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// ListInstances: Lists the instances in the specified instance group
// and displays information about the named ports. Depending on the
// specified options, this method can list all instances or only the
// instances that are running. (== suppress_warning http-rest-shadowed
// ==)
func (r *RegionInstanceGroupsService) ListInstances(project string, region string, instanceGroup string, regioninstancegroupslistinstancesrequest *RegionInstanceGroupsListInstancesRequest) *RegionInstanceGroupsListInstancesCall {
	c := &RegionInstanceGroupsListInstancesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroup = instanceGroup
	c.regioninstancegroupslistinstancesrequest = regioninstancegroupslistinstancesrequest
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionInstanceGroupsListInstancesCall) Filter(filter string) *RegionInstanceGroupsListInstancesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionInstanceGroupsListInstancesCall) MaxResults(maxResults int64) *RegionInstanceGroupsListInstancesCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionInstanceGroupsListInstancesCall) OrderBy(orderBy string) *RegionInstanceGroupsListInstancesCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionInstanceGroupsListInstancesCall) PageToken(pageToken string) *RegionInstanceGroupsListInstancesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupsListInstancesCall) Fields(s ...googleapi.Field) *RegionInstanceGroupsListInstancesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupsListInstancesCall) Context(ctx context.Context) *RegionInstanceGroupsListInstancesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupsListInstancesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupsListInstancesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regioninstancegroupslistinstancesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroups/{instanceGroup}/listInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"region":        c.region,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroups.listInstances" call.
// Exactly one of *RegionInstanceGroupsListInstances or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *RegionInstanceGroupsListInstances.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *RegionInstanceGroupsListInstancesCall) Do(opts ...googleapi.CallOption) (*RegionInstanceGroupsListInstances, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionInstanceGroupsListInstances{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists the instances in the specified instance group and displays information about the named ports. Depending on the specified options, this method can list all instances or only the instances that are running. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroups.listInstances",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "instanceGroup": {
	//       "description": "Name of the regional instance group for which we want to list the instances.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroups/{instanceGroup}/listInstances",
	//   "request": {
	//     "$ref": "RegionInstanceGroupsListInstancesRequest"
	//   },
	//   "response": {
	//     "$ref": "RegionInstanceGroupsListInstances"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionInstanceGroupsListInstancesCall) Pages(ctx context.Context, f func(*RegionInstanceGroupsListInstances) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionInstanceGroups.setNamedPorts":

type RegionInstanceGroupsSetNamedPortsCall struct {
	s                                        *Service
	project                                  string
	region                                   string
	instanceGroup                            string
	regioninstancegroupssetnamedportsrequest *RegionInstanceGroupsSetNamedPortsRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// SetNamedPorts: Sets the named ports for the specified regional
// instance group. (== suppress_warning http-rest-shadowed ==)
func (r *RegionInstanceGroupsService) SetNamedPorts(project string, region string, instanceGroup string, regioninstancegroupssetnamedportsrequest *RegionInstanceGroupsSetNamedPortsRequest) *RegionInstanceGroupsSetNamedPortsCall {
	c := &RegionInstanceGroupsSetNamedPortsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.instanceGroup = instanceGroup
	c.regioninstancegroupssetnamedportsrequest = regioninstancegroupssetnamedportsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionInstanceGroupsSetNamedPortsCall) RequestId(requestId string) *RegionInstanceGroupsSetNamedPortsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionInstanceGroupsSetNamedPortsCall) Fields(s ...googleapi.Field) *RegionInstanceGroupsSetNamedPortsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionInstanceGroupsSetNamedPortsCall) Context(ctx context.Context) *RegionInstanceGroupsSetNamedPortsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionInstanceGroupsSetNamedPortsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionInstanceGroupsSetNamedPortsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regioninstancegroupssetnamedportsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/instanceGroups/{instanceGroup}/setNamedPorts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":       c.project,
		"region":        c.region,
		"instanceGroup": c.instanceGroup,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionInstanceGroups.setNamedPorts" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionInstanceGroupsSetNamedPortsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the named ports for the specified regional instance group. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionInstanceGroups.setNamedPorts",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "instanceGroup"
	//   ],
	//   "parameters": {
	//     "instanceGroup": {
	//       "description": "The name of the regional instance group where the named ports are updated.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/instanceGroups/{instanceGroup}/setNamedPorts",
	//   "request": {
	//     "$ref": "RegionInstanceGroupsSetNamedPortsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionOperations.delete":

type RegionOperationsDeleteCall struct {
	s          *Service
	project    string
	region     string
	operation  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified region-specific Operations resource.
// (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/regionOperations/delete
func (r *RegionOperationsService) Delete(project string, region string, operation string) *RegionOperationsDeleteCall {
	c := &RegionOperationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.operation = operation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionOperationsDeleteCall) Fields(s ...googleapi.Field) *RegionOperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionOperationsDeleteCall) Context(ctx context.Context) *RegionOperationsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionOperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionOperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/operations/{operation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"region":    c.region,
		"operation": c.operation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionOperations.delete" call.
func (c *RegionOperationsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes the specified region-specific Operations resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionOperations.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "operation"
	//   ],
	//   "parameters": {
	//     "operation": {
	//       "description": "Name of the Operations resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/operations/{operation}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionOperations.get":

type RegionOperationsGetCall struct {
	s            *Service
	project      string
	region       string
	operation    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified region-specific Operations resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/regionOperations/get
func (r *RegionOperationsService) Get(project string, region string, operation string) *RegionOperationsGetCall {
	c := &RegionOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.operation = operation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionOperationsGetCall) Fields(s ...googleapi.Field) *RegionOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionOperationsGetCall) IfNoneMatch(entityTag string) *RegionOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionOperationsGetCall) Context(ctx context.Context) *RegionOperationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/operations/{operation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"region":    c.region,
		"operation": c.operation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionOperations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the specified region-specific Operations resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionOperations.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "operation"
	//   ],
	//   "parameters": {
	//     "operation": {
	//       "description": "Name of the Operations resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/operations/{operation}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionOperations.list":

type RegionOperationsListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of Operation resources contained within the
// specified region. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/regionOperations/list
func (r *RegionOperationsService) List(project string, region string) *RegionOperationsListCall {
	c := &RegionOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionOperationsListCall) Filter(filter string) *RegionOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionOperationsListCall) MaxResults(maxResults int64) *RegionOperationsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionOperationsListCall) OrderBy(orderBy string) *RegionOperationsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionOperationsListCall) PageToken(pageToken string) *RegionOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionOperationsListCall) Fields(s ...googleapi.Field) *RegionOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionOperationsListCall) IfNoneMatch(entityTag string) *RegionOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionOperationsListCall) Context(ctx context.Context) *RegionOperationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionOperations.list" call.
// Exactly one of *OperationList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *OperationList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionOperationsListCall) Do(opts ...googleapi.CallOption) (*OperationList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperationList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of Operation resources contained within the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionOperations.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/operations",
	//   "response": {
	//     "$ref": "OperationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionOperationsListCall) Pages(ctx context.Context, f func(*OperationList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionSslCertificates.delete":

type RegionSslCertificatesDeleteCall struct {
	s              *Service
	project        string
	region         string
	sslCertificate string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified SslCertificate resource in the region.
// (== suppress_warning http-rest-shadowed ==)
func (r *RegionSslCertificatesService) Delete(project string, region string, sslCertificate string) *RegionSslCertificatesDeleteCall {
	c := &RegionSslCertificatesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.sslCertificate = sslCertificate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionSslCertificatesDeleteCall) RequestId(requestId string) *RegionSslCertificatesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionSslCertificatesDeleteCall) Fields(s ...googleapi.Field) *RegionSslCertificatesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionSslCertificatesDeleteCall) Context(ctx context.Context) *RegionSslCertificatesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionSslCertificatesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionSslCertificatesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/sslCertificates/{sslCertificate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"sslCertificate": c.sslCertificate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionSslCertificates.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionSslCertificatesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified SslCertificate resource in the region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionSslCertificates.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "sslCertificate"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sslCertificate": {
	//       "description": "Name of the SslCertificate resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/sslCertificates/{sslCertificate}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionSslCertificates.get":

type RegionSslCertificatesGetCall struct {
	s              *Service
	project        string
	region         string
	sslCertificate string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified SslCertificate resource in the specified
// region. Get a list of available SSL certificates by making a list()
// request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionSslCertificatesService) Get(project string, region string, sslCertificate string) *RegionSslCertificatesGetCall {
	c := &RegionSslCertificatesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.sslCertificate = sslCertificate
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionSslCertificatesGetCall) Fields(s ...googleapi.Field) *RegionSslCertificatesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionSslCertificatesGetCall) IfNoneMatch(entityTag string) *RegionSslCertificatesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionSslCertificatesGetCall) Context(ctx context.Context) *RegionSslCertificatesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionSslCertificatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionSslCertificatesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/sslCertificates/{sslCertificate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"sslCertificate": c.sslCertificate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionSslCertificates.get" call.
// Exactly one of *SslCertificate or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SslCertificate.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionSslCertificatesGetCall) Do(opts ...googleapi.CallOption) (*SslCertificate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslCertificate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified SslCertificate resource in the specified region. Get a list of available SSL certificates by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionSslCertificates.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "sslCertificate"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sslCertificate": {
	//       "description": "Name of the SslCertificate resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/sslCertificates/{sslCertificate}",
	//   "response": {
	//     "$ref": "SslCertificate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionSslCertificates.insert":

type RegionSslCertificatesInsertCall struct {
	s              *Service
	project        string
	region         string
	sslcertificate *SslCertificate
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a SslCertificate resource in the specified project
// and region using the data included in the request (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionSslCertificatesService) Insert(project string, region string, sslcertificate *SslCertificate) *RegionSslCertificatesInsertCall {
	c := &RegionSslCertificatesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.sslcertificate = sslcertificate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionSslCertificatesInsertCall) RequestId(requestId string) *RegionSslCertificatesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionSslCertificatesInsertCall) Fields(s ...googleapi.Field) *RegionSslCertificatesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionSslCertificatesInsertCall) Context(ctx context.Context) *RegionSslCertificatesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionSslCertificatesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionSslCertificatesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.sslcertificate)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/sslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionSslCertificates.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionSslCertificatesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a SslCertificate resource in the specified project and region using the data included in the request (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionSslCertificates.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/sslCertificates",
	//   "request": {
	//     "$ref": "SslCertificate"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionSslCertificates.list":

type RegionSslCertificatesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of SslCertificate resources available to the
// specified project in the specified region. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionSslCertificatesService) List(project string, region string) *RegionSslCertificatesListCall {
	c := &RegionSslCertificatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionSslCertificatesListCall) Filter(filter string) *RegionSslCertificatesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionSslCertificatesListCall) MaxResults(maxResults int64) *RegionSslCertificatesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionSslCertificatesListCall) OrderBy(orderBy string) *RegionSslCertificatesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionSslCertificatesListCall) PageToken(pageToken string) *RegionSslCertificatesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionSslCertificatesListCall) Fields(s ...googleapi.Field) *RegionSslCertificatesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionSslCertificatesListCall) IfNoneMatch(entityTag string) *RegionSslCertificatesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionSslCertificatesListCall) Context(ctx context.Context) *RegionSslCertificatesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionSslCertificatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionSslCertificatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/sslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionSslCertificates.list" call.
// Exactly one of *SslCertificateList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SslCertificateList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionSslCertificatesListCall) Do(opts ...googleapi.CallOption) (*SslCertificateList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslCertificateList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of SslCertificate resources available to the specified project in the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionSslCertificates.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/sslCertificates",
	//   "response": {
	//     "$ref": "SslCertificateList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionSslCertificatesListCall) Pages(ctx context.Context, f func(*SslCertificateList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionTargetHttpProxies.delete":

type RegionTargetHttpProxiesDeleteCall struct {
	s               *Service
	project         string
	region          string
	targetHttpProxy string
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Delete: Deletes the specified TargetHttpProxy resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpProxiesService) Delete(project string, region string, targetHttpProxy string) *RegionTargetHttpProxiesDeleteCall {
	c := &RegionTargetHttpProxiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetHttpProxy = targetHttpProxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionTargetHttpProxiesDeleteCall) RequestId(requestId string) *RegionTargetHttpProxiesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpProxiesDeleteCall) Fields(s ...googleapi.Field) *RegionTargetHttpProxiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpProxiesDeleteCall) Context(ctx context.Context) *RegionTargetHttpProxiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpProxiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpProxiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpProxies/{targetHttpProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"region":          c.region,
		"targetHttpProxy": c.targetHttpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpProxies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionTargetHttpProxiesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified TargetHttpProxy resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionTargetHttpProxies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetHttpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpProxy": {
	//       "description": "Name of the TargetHttpProxy resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpProxies/{targetHttpProxy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionTargetHttpProxies.get":

type RegionTargetHttpProxiesGetCall struct {
	s               *Service
	project         string
	region          string
	targetHttpProxy string
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
	header_         http.Header
}

// Get: Returns the specified TargetHttpProxy resource in the specified
// region. Gets a list of available target HTTP proxies by making a
// list() request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpProxiesService) Get(project string, region string, targetHttpProxy string) *RegionTargetHttpProxiesGetCall {
	c := &RegionTargetHttpProxiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetHttpProxy = targetHttpProxy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpProxiesGetCall) Fields(s ...googleapi.Field) *RegionTargetHttpProxiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionTargetHttpProxiesGetCall) IfNoneMatch(entityTag string) *RegionTargetHttpProxiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpProxiesGetCall) Context(ctx context.Context) *RegionTargetHttpProxiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpProxiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpProxiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpProxies/{targetHttpProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"region":          c.region,
		"targetHttpProxy": c.targetHttpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpProxies.get" call.
// Exactly one of *TargetHttpProxy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetHttpProxy.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionTargetHttpProxiesGetCall) Do(opts ...googleapi.CallOption) (*TargetHttpProxy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpProxy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified TargetHttpProxy resource in the specified region. Gets a list of available target HTTP proxies by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionTargetHttpProxies.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetHttpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetHttpProxy": {
	//       "description": "Name of the TargetHttpProxy resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpProxies/{targetHttpProxy}",
	//   "response": {
	//     "$ref": "TargetHttpProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionTargetHttpProxies.insert":

type RegionTargetHttpProxiesInsertCall struct {
	s               *Service
	project         string
	region          string
	targethttpproxy *TargetHttpProxy
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Creates a TargetHttpProxy resource in the specified project
// and region using the data included in the request. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpProxiesService) Insert(project string, region string, targethttpproxy *TargetHttpProxy) *RegionTargetHttpProxiesInsertCall {
	c := &RegionTargetHttpProxiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targethttpproxy = targethttpproxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionTargetHttpProxiesInsertCall) RequestId(requestId string) *RegionTargetHttpProxiesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpProxiesInsertCall) Fields(s ...googleapi.Field) *RegionTargetHttpProxiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpProxiesInsertCall) Context(ctx context.Context) *RegionTargetHttpProxiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpProxiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpProxiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targethttpproxy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpProxies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionTargetHttpProxiesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a TargetHttpProxy resource in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionTargetHttpProxies.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpProxies",
	//   "request": {
	//     "$ref": "TargetHttpProxy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionTargetHttpProxies.list":

type RegionTargetHttpProxiesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of TargetHttpProxy resources available to
// the specified project in the specified region. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionTargetHttpProxiesService) List(project string, region string) *RegionTargetHttpProxiesListCall {
	c := &RegionTargetHttpProxiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionTargetHttpProxiesListCall) Filter(filter string) *RegionTargetHttpProxiesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionTargetHttpProxiesListCall) MaxResults(maxResults int64) *RegionTargetHttpProxiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionTargetHttpProxiesListCall) OrderBy(orderBy string) *RegionTargetHttpProxiesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionTargetHttpProxiesListCall) PageToken(pageToken string) *RegionTargetHttpProxiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpProxiesListCall) Fields(s ...googleapi.Field) *RegionTargetHttpProxiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionTargetHttpProxiesListCall) IfNoneMatch(entityTag string) *RegionTargetHttpProxiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpProxiesListCall) Context(ctx context.Context) *RegionTargetHttpProxiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpProxiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpProxiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpProxies.list" call.
// Exactly one of *TargetHttpProxyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetHttpProxyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionTargetHttpProxiesListCall) Do(opts ...googleapi.CallOption) (*TargetHttpProxyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpProxyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of TargetHttpProxy resources available to the specified project in the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionTargetHttpProxies.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpProxies",
	//   "response": {
	//     "$ref": "TargetHttpProxyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionTargetHttpProxiesListCall) Pages(ctx context.Context, f func(*TargetHttpProxyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionTargetHttpProxies.setUrlMap":

type RegionTargetHttpProxiesSetUrlMapCall struct {
	s               *Service
	project         string
	region          string
	targetHttpProxy string
	urlmapreference *UrlMapReference
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// SetUrlMap: Changes the URL map for TargetHttpProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpProxiesService) SetUrlMap(project string, region string, targetHttpProxy string, urlmapreference *UrlMapReference) *RegionTargetHttpProxiesSetUrlMapCall {
	c := &RegionTargetHttpProxiesSetUrlMapCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetHttpProxy = targetHttpProxy
	c.urlmapreference = urlmapreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionTargetHttpProxiesSetUrlMapCall) RequestId(requestId string) *RegionTargetHttpProxiesSetUrlMapCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpProxiesSetUrlMapCall) Fields(s ...googleapi.Field) *RegionTargetHttpProxiesSetUrlMapCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpProxiesSetUrlMapCall) Context(ctx context.Context) *RegionTargetHttpProxiesSetUrlMapCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpProxiesSetUrlMapCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpProxiesSetUrlMapCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmapreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpProxies/{targetHttpProxy}/setUrlMap")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"region":          c.region,
		"targetHttpProxy": c.targetHttpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpProxies.setUrlMap" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionTargetHttpProxiesSetUrlMapCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the URL map for TargetHttpProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionTargetHttpProxies.setUrlMap",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetHttpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpProxy": {
	//       "description": "Name of the TargetHttpProxy to set a URL map for.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpProxies/{targetHttpProxy}/setUrlMap",
	//   "request": {
	//     "$ref": "UrlMapReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionTargetHttpsProxies.delete":

type RegionTargetHttpsProxiesDeleteCall struct {
	s                *Service
	project          string
	region           string
	targetHttpsProxy string
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Delete: Deletes the specified TargetHttpsProxy resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpsProxiesService) Delete(project string, region string, targetHttpsProxy string) *RegionTargetHttpsProxiesDeleteCall {
	c := &RegionTargetHttpsProxiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetHttpsProxy = targetHttpsProxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionTargetHttpsProxiesDeleteCall) RequestId(requestId string) *RegionTargetHttpsProxiesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpsProxiesDeleteCall) Fields(s ...googleapi.Field) *RegionTargetHttpsProxiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpsProxiesDeleteCall) Context(ctx context.Context) *RegionTargetHttpsProxiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpsProxiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpsProxiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"region":           c.region,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpsProxies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionTargetHttpsProxiesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified TargetHttpsProxy resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionTargetHttpsProxies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionTargetHttpsProxies.get":

type RegionTargetHttpsProxiesGetCall struct {
	s                *Service
	project          string
	region           string
	targetHttpsProxy string
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// Get: Returns the specified TargetHttpsProxy resource in the specified
// region. Gets a list of available target HTTP proxies by making a
// list() request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpsProxiesService) Get(project string, region string, targetHttpsProxy string) *RegionTargetHttpsProxiesGetCall {
	c := &RegionTargetHttpsProxiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetHttpsProxy = targetHttpsProxy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpsProxiesGetCall) Fields(s ...googleapi.Field) *RegionTargetHttpsProxiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionTargetHttpsProxiesGetCall) IfNoneMatch(entityTag string) *RegionTargetHttpsProxiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpsProxiesGetCall) Context(ctx context.Context) *RegionTargetHttpsProxiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpsProxiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpsProxiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"region":           c.region,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpsProxies.get" call.
// Exactly one of *TargetHttpsProxy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetHttpsProxy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionTargetHttpsProxiesGetCall) Do(opts ...googleapi.CallOption) (*TargetHttpsProxy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpsProxy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified TargetHttpsProxy resource in the specified region. Gets a list of available target HTTP proxies by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionTargetHttpsProxies.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}",
	//   "response": {
	//     "$ref": "TargetHttpsProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionTargetHttpsProxies.insert":

type RegionTargetHttpsProxiesInsertCall struct {
	s                *Service
	project          string
	region           string
	targethttpsproxy *TargetHttpsProxy
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Insert: Creates a TargetHttpsProxy resource in the specified project
// and region using the data included in the request. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpsProxiesService) Insert(project string, region string, targethttpsproxy *TargetHttpsProxy) *RegionTargetHttpsProxiesInsertCall {
	c := &RegionTargetHttpsProxiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targethttpsproxy = targethttpsproxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionTargetHttpsProxiesInsertCall) RequestId(requestId string) *RegionTargetHttpsProxiesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpsProxiesInsertCall) Fields(s ...googleapi.Field) *RegionTargetHttpsProxiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpsProxiesInsertCall) Context(ctx context.Context) *RegionTargetHttpsProxiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpsProxiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpsProxiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targethttpsproxy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpsProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpsProxies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionTargetHttpsProxiesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a TargetHttpsProxy resource in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionTargetHttpsProxies.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpsProxies",
	//   "request": {
	//     "$ref": "TargetHttpsProxy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionTargetHttpsProxies.list":

type RegionTargetHttpsProxiesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of TargetHttpsProxy resources available to
// the specified project in the specified region. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionTargetHttpsProxiesService) List(project string, region string) *RegionTargetHttpsProxiesListCall {
	c := &RegionTargetHttpsProxiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionTargetHttpsProxiesListCall) Filter(filter string) *RegionTargetHttpsProxiesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionTargetHttpsProxiesListCall) MaxResults(maxResults int64) *RegionTargetHttpsProxiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionTargetHttpsProxiesListCall) OrderBy(orderBy string) *RegionTargetHttpsProxiesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionTargetHttpsProxiesListCall) PageToken(pageToken string) *RegionTargetHttpsProxiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpsProxiesListCall) Fields(s ...googleapi.Field) *RegionTargetHttpsProxiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionTargetHttpsProxiesListCall) IfNoneMatch(entityTag string) *RegionTargetHttpsProxiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpsProxiesListCall) Context(ctx context.Context) *RegionTargetHttpsProxiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpsProxiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpsProxiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpsProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpsProxies.list" call.
// Exactly one of *TargetHttpsProxyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetHttpsProxyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionTargetHttpsProxiesListCall) Do(opts ...googleapi.CallOption) (*TargetHttpsProxyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpsProxyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of TargetHttpsProxy resources available to the specified project in the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionTargetHttpsProxies.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpsProxies",
	//   "response": {
	//     "$ref": "TargetHttpsProxyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionTargetHttpsProxiesListCall) Pages(ctx context.Context, f func(*TargetHttpsProxyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionTargetHttpsProxies.setSslCertificates":

type RegionTargetHttpsProxiesSetSslCertificatesCall struct {
	s                                                 *Service
	project                                           string
	region                                            string
	targetHttpsProxy                                  string
	regiontargethttpsproxiessetsslcertificatesrequest *RegionTargetHttpsProxiesSetSslCertificatesRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// SetSslCertificates: Replaces SslCertificates for TargetHttpsProxy.
// (== suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpsProxiesService) SetSslCertificates(project string, region string, targetHttpsProxy string, regiontargethttpsproxiessetsslcertificatesrequest *RegionTargetHttpsProxiesSetSslCertificatesRequest) *RegionTargetHttpsProxiesSetSslCertificatesCall {
	c := &RegionTargetHttpsProxiesSetSslCertificatesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetHttpsProxy = targetHttpsProxy
	c.regiontargethttpsproxiessetsslcertificatesrequest = regiontargethttpsproxiessetsslcertificatesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionTargetHttpsProxiesSetSslCertificatesCall) RequestId(requestId string) *RegionTargetHttpsProxiesSetSslCertificatesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpsProxiesSetSslCertificatesCall) Fields(s ...googleapi.Field) *RegionTargetHttpsProxiesSetSslCertificatesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpsProxiesSetSslCertificatesCall) Context(ctx context.Context) *RegionTargetHttpsProxiesSetSslCertificatesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpsProxiesSetSslCertificatesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpsProxiesSetSslCertificatesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regiontargethttpsproxiessetsslcertificatesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}/setSslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"region":           c.region,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpsProxies.setSslCertificates" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionTargetHttpsProxiesSetSslCertificatesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Replaces SslCertificates for TargetHttpsProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionTargetHttpsProxies.setSslCertificates",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource to set an SslCertificates resource for.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}/setSslCertificates",
	//   "request": {
	//     "$ref": "RegionTargetHttpsProxiesSetSslCertificatesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionTargetHttpsProxies.setUrlMap":

type RegionTargetHttpsProxiesSetUrlMapCall struct {
	s                *Service
	project          string
	region           string
	targetHttpsProxy string
	urlmapreference  *UrlMapReference
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// SetUrlMap: Changes the URL map for TargetHttpsProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *RegionTargetHttpsProxiesService) SetUrlMap(project string, region string, targetHttpsProxy string, urlmapreference *UrlMapReference) *RegionTargetHttpsProxiesSetUrlMapCall {
	c := &RegionTargetHttpsProxiesSetUrlMapCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetHttpsProxy = targetHttpsProxy
	c.urlmapreference = urlmapreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RegionTargetHttpsProxiesSetUrlMapCall) RequestId(requestId string) *RegionTargetHttpsProxiesSetUrlMapCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionTargetHttpsProxiesSetUrlMapCall) Fields(s ...googleapi.Field) *RegionTargetHttpsProxiesSetUrlMapCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionTargetHttpsProxiesSetUrlMapCall) Context(ctx context.Context) *RegionTargetHttpsProxiesSetUrlMapCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionTargetHttpsProxiesSetUrlMapCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionTargetHttpsProxiesSetUrlMapCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmapreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}/setUrlMap")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"region":           c.region,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionTargetHttpsProxies.setUrlMap" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionTargetHttpsProxiesSetUrlMapCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the URL map for TargetHttpsProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionTargetHttpsProxies.setUrlMap",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy to set a URL map for.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetHttpsProxies/{targetHttpsProxy}/setUrlMap",
	//   "request": {
	//     "$ref": "UrlMapReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionUrlMaps.delete":

type RegionUrlMapsDeleteCall struct {
	s          *Service
	project    string
	region     string
	urlMap     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified UrlMap resource. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionUrlMapsService) Delete(project string, region string, urlMap string) *RegionUrlMapsDeleteCall {
	c := &RegionUrlMapsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.urlMap = urlMap
	return c
}

// RequestId sets the optional parameter "requestId": begin_interface:
// MixerMutationRequestBuilder Request ID to support idempotency.
func (c *RegionUrlMapsDeleteCall) RequestId(requestId string) *RegionUrlMapsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionUrlMapsDeleteCall) Fields(s ...googleapi.Field) *RegionUrlMapsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionUrlMapsDeleteCall) Context(ctx context.Context) *RegionUrlMapsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionUrlMapsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionUrlMapsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionUrlMaps.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionUrlMapsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified UrlMap resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.regionUrlMaps.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "begin_interface: MixerMutationRequestBuilder Request ID to support idempotency.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/urlMaps/{urlMap}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionUrlMaps.get":

type RegionUrlMapsGetCall struct {
	s            *Service
	project      string
	region       string
	urlMap       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified UrlMap resource. Gets a list of available
// URL maps by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionUrlMapsService) Get(project string, region string, urlMap string) *RegionUrlMapsGetCall {
	c := &RegionUrlMapsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.urlMap = urlMap
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionUrlMapsGetCall) Fields(s ...googleapi.Field) *RegionUrlMapsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionUrlMapsGetCall) IfNoneMatch(entityTag string) *RegionUrlMapsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionUrlMapsGetCall) Context(ctx context.Context) *RegionUrlMapsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionUrlMapsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionUrlMapsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionUrlMaps.get" call.
// Exactly one of *UrlMap or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UrlMap.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *RegionUrlMapsGetCall) Do(opts ...googleapi.CallOption) (*UrlMap, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UrlMap{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified UrlMap resource. Gets a list of available URL maps by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionUrlMaps.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/urlMaps/{urlMap}",
	//   "response": {
	//     "$ref": "UrlMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regionUrlMaps.insert":

type RegionUrlMapsInsertCall struct {
	s          *Service
	project    string
	region     string
	urlmap     *UrlMap
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a UrlMap resource in the specified project using the
// data included in the request. (== suppress_warning http-rest-shadowed
// ==)
func (r *RegionUrlMapsService) Insert(project string, region string, urlmap *UrlMap) *RegionUrlMapsInsertCall {
	c := &RegionUrlMapsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.urlmap = urlmap
	return c
}

// RequestId sets the optional parameter "requestId": begin_interface:
// MixerMutationRequestBuilder Request ID to support idempotency.
func (c *RegionUrlMapsInsertCall) RequestId(requestId string) *RegionUrlMapsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionUrlMapsInsertCall) Fields(s ...googleapi.Field) *RegionUrlMapsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionUrlMapsInsertCall) Context(ctx context.Context) *RegionUrlMapsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionUrlMapsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionUrlMapsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/urlMaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionUrlMaps.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionUrlMapsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a UrlMap resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionUrlMaps.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "begin_interface: MixerMutationRequestBuilder Request ID to support idempotency.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/urlMaps",
	//   "request": {
	//     "$ref": "UrlMap"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionUrlMaps.list":

type RegionUrlMapsListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of UrlMap resources available to the
// specified project in the specified region. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionUrlMapsService) List(project string, region string) *RegionUrlMapsListCall {
	c := &RegionUrlMapsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionUrlMapsListCall) Filter(filter string) *RegionUrlMapsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionUrlMapsListCall) MaxResults(maxResults int64) *RegionUrlMapsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionUrlMapsListCall) OrderBy(orderBy string) *RegionUrlMapsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionUrlMapsListCall) PageToken(pageToken string) *RegionUrlMapsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionUrlMapsListCall) Fields(s ...googleapi.Field) *RegionUrlMapsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionUrlMapsListCall) IfNoneMatch(entityTag string) *RegionUrlMapsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionUrlMapsListCall) Context(ctx context.Context) *RegionUrlMapsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionUrlMapsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionUrlMapsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/urlMaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionUrlMaps.list" call.
// Exactly one of *UrlMapList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UrlMapList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionUrlMapsListCall) Do(opts ...googleapi.CallOption) (*UrlMapList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UrlMapList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of UrlMap resources available to the specified project in the specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regionUrlMaps.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/urlMaps",
	//   "response": {
	//     "$ref": "UrlMapList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionUrlMapsListCall) Pages(ctx context.Context, f func(*UrlMapList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.regionUrlMaps.patch":

type RegionUrlMapsPatchCall struct {
	s          *Service
	project    string
	region     string
	urlMap     string
	urlmap     *UrlMap
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Patches the specified UrlMap resource with the data included
// in the request. This method supports PATCH semantics and uses JSON
// merge patch format and processing rules. (== suppress_warning
// http-rest-shadowed ==)
func (r *RegionUrlMapsService) Patch(project string, region string, urlMap string, urlmap *UrlMap) *RegionUrlMapsPatchCall {
	c := &RegionUrlMapsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.urlMap = urlMap
	c.urlmap = urlmap
	return c
}

// RequestId sets the optional parameter "requestId": begin_interface:
// MixerMutationRequestBuilder Request ID to support idempotency.
func (c *RegionUrlMapsPatchCall) RequestId(requestId string) *RegionUrlMapsPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionUrlMapsPatchCall) Fields(s ...googleapi.Field) *RegionUrlMapsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionUrlMapsPatchCall) Context(ctx context.Context) *RegionUrlMapsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionUrlMapsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionUrlMapsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionUrlMaps.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionUrlMapsPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified UrlMap resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.regionUrlMaps.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "begin_interface: MixerMutationRequestBuilder Request ID to support idempotency.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/urlMaps/{urlMap}",
	//   "request": {
	//     "$ref": "UrlMap"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionUrlMaps.update":

type RegionUrlMapsUpdateCall struct {
	s          *Service
	project    string
	region     string
	urlMap     string
	urlmap     *UrlMap
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates the specified UrlMap resource with the data included
// in the request. (== suppress_warning http-rest-shadowed ==)
func (r *RegionUrlMapsService) Update(project string, region string, urlMap string, urlmap *UrlMap) *RegionUrlMapsUpdateCall {
	c := &RegionUrlMapsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.urlMap = urlMap
	c.urlmap = urlmap
	return c
}

// RequestId sets the optional parameter "requestId": begin_interface:
// MixerMutationRequestBuilder Request ID to support idempotency.
func (c *RegionUrlMapsUpdateCall) RequestId(requestId string) *RegionUrlMapsUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionUrlMapsUpdateCall) Fields(s ...googleapi.Field) *RegionUrlMapsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionUrlMapsUpdateCall) Context(ctx context.Context) *RegionUrlMapsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionUrlMapsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionUrlMapsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionUrlMaps.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionUrlMapsUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified UrlMap resource with the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.regionUrlMaps.update",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "begin_interface: MixerMutationRequestBuilder Request ID to support idempotency.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/urlMaps/{urlMap}",
	//   "request": {
	//     "$ref": "UrlMap"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regionUrlMaps.validate":

type RegionUrlMapsValidateCall struct {
	s                            *Service
	project                      string
	region                       string
	urlMap                       string
	regionurlmapsvalidaterequest *RegionUrlMapsValidateRequest
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Validate: Runs static validation for the UrlMap. In particular, the
// tests of the provided UrlMap will be run. Calling this method does
// NOT create the UrlMap. (== suppress_warning http-rest-shadowed ==)
func (r *RegionUrlMapsService) Validate(project string, region string, urlMap string, regionurlmapsvalidaterequest *RegionUrlMapsValidateRequest) *RegionUrlMapsValidateCall {
	c := &RegionUrlMapsValidateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.urlMap = urlMap
	c.regionurlmapsvalidaterequest = regionurlmapsvalidaterequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionUrlMapsValidateCall) Fields(s ...googleapi.Field) *RegionUrlMapsValidateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionUrlMapsValidateCall) Context(ctx context.Context) *RegionUrlMapsValidateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionUrlMapsValidateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionUrlMapsValidateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regionurlmapsvalidaterequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/urlMaps/{urlMap}/validate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regionUrlMaps.validate" call.
// Exactly one of *UrlMapsValidateResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UrlMapsValidateResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionUrlMapsValidateCall) Do(opts ...googleapi.CallOption) (*UrlMapsValidateResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UrlMapsValidateResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Runs static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.regionUrlMaps.validate",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to be validated as.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/urlMaps/{urlMap}/validate",
	//   "request": {
	//     "$ref": "RegionUrlMapsValidateRequest"
	//   },
	//   "response": {
	//     "$ref": "UrlMapsValidateResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.regions.get":

type RegionsGetCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified Region resource. Gets a list of available
// regions by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/regions/get
func (r *RegionsService) Get(project string, region string) *RegionsGetCall {
	c := &RegionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionsGetCall) Fields(s ...googleapi.Field) *RegionsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionsGetCall) IfNoneMatch(entityTag string) *RegionsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionsGetCall) Context(ctx context.Context) *RegionsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regions.get" call.
// Exactly one of *Region or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Region.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *RegionsGetCall) Do(opts ...googleapi.CallOption) (*Region, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Region{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified Region resource. Gets a list of available regions by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regions.get",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}",
	//   "response": {
	//     "$ref": "Region"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.regions.list":

type RegionsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of region resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/regions/list
func (r *RegionsService) List(project string) *RegionsListCall {
	c := &RegionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RegionsListCall) Filter(filter string) *RegionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RegionsListCall) MaxResults(maxResults int64) *RegionsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RegionsListCall) OrderBy(orderBy string) *RegionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RegionsListCall) PageToken(pageToken string) *RegionsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionsListCall) Fields(s ...googleapi.Field) *RegionsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionsListCall) IfNoneMatch(entityTag string) *RegionsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionsListCall) Context(ctx context.Context) *RegionsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.regions.list" call.
// Exactly one of *RegionList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RegionList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RegionsListCall) Do(opts ...googleapi.CallOption) (*RegionList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of region resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.regions.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions",
	//   "response": {
	//     "$ref": "RegionList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RegionsListCall) Pages(ctx context.Context, f func(*RegionList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.reservations.aggregatedList":

type ReservationsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of reservations. (==
// suppress_warning http-rest-shadowed ==)
func (r *ReservationsService) AggregatedList(project string) *ReservationsAggregatedListCall {
	c := &ReservationsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ReservationsAggregatedListCall) Filter(filter string) *ReservationsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ReservationsAggregatedListCall) MaxResults(maxResults int64) *ReservationsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ReservationsAggregatedListCall) OrderBy(orderBy string) *ReservationsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ReservationsAggregatedListCall) PageToken(pageToken string) *ReservationsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsAggregatedListCall) Fields(s ...googleapi.Field) *ReservationsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReservationsAggregatedListCall) IfNoneMatch(entityTag string) *ReservationsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsAggregatedListCall) Context(ctx context.Context) *ReservationsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/reservations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.aggregatedList" call.
// Exactly one of *ReservationAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ReservationAggregatedList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ReservationsAggregatedListCall) Do(opts ...googleapi.CallOption) (*ReservationAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ReservationAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of reservations. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.reservations.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/reservations",
	//   "response": {
	//     "$ref": "ReservationAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ReservationsAggregatedListCall) Pages(ctx context.Context, f func(*ReservationAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.reservations.delete":

type ReservationsDeleteCall struct {
	s           *Service
	project     string
	zone        string
	reservation string
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Delete: Deletes the specified reservation. (== suppress_warning
// http-rest-shadowed ==)
func (r *ReservationsService) Delete(project string, zone string, reservation string) *ReservationsDeleteCall {
	c := &ReservationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.reservation = reservation
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ReservationsDeleteCall) RequestId(requestId string) *ReservationsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsDeleteCall) Fields(s ...googleapi.Field) *ReservationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsDeleteCall) Context(ctx context.Context) *ReservationsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations/{reservation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"zone":        c.zone,
		"reservation": c.reservation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReservationsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified reservation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.reservations.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "reservation"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "reservation": {
	//       "description": "Name of the reservation to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations/{reservation}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.reservations.get":

type ReservationsGetCall struct {
	s            *Service
	project      string
	zone         string
	reservation  string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves information about the specified reservation. (==
// suppress_warning http-rest-shadowed ==)
func (r *ReservationsService) Get(project string, zone string, reservation string) *ReservationsGetCall {
	c := &ReservationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.reservation = reservation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsGetCall) Fields(s ...googleapi.Field) *ReservationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReservationsGetCall) IfNoneMatch(entityTag string) *ReservationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsGetCall) Context(ctx context.Context) *ReservationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations/{reservation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"zone":        c.zone,
		"reservation": c.reservation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.get" call.
// Exactly one of *Reservation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Reservation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReservationsGetCall) Do(opts ...googleapi.CallOption) (*Reservation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Reservation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves information about the specified reservation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.reservations.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "reservation"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reservation": {
	//       "description": "Name of the reservation to retrieve.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations/{reservation}",
	//   "response": {
	//     "$ref": "Reservation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.reservations.getIamPolicy":

type ReservationsGetIamPolicyCall struct {
	s            *Service
	project      string
	zone         string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *ReservationsService) GetIamPolicy(project string, zone string, resource string) *ReservationsGetIamPolicyCall {
	c := &ReservationsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsGetIamPolicyCall) Fields(s ...googleapi.Field) *ReservationsGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReservationsGetIamPolicyCall) IfNoneMatch(entityTag string) *ReservationsGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsGetIamPolicyCall) Context(ctx context.Context) *ReservationsGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReservationsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.reservations.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.reservations.insert":

type ReservationsInsertCall struct {
	s           *Service
	project     string
	zone        string
	reservation *Reservation
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Insert: Creates a new reservation. For more information, read
// Reserving zonal resources. (== suppress_warning http-rest-shadowed
// ==)
func (r *ReservationsService) Insert(project string, zone string, reservation *Reservation) *ReservationsInsertCall {
	c := &ReservationsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.reservation = reservation
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ReservationsInsertCall) RequestId(requestId string) *ReservationsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsInsertCall) Fields(s ...googleapi.Field) *ReservationsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsInsertCall) Context(ctx context.Context) *ReservationsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.reservation)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReservationsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new reservation. For more information, read Reserving zonal resources. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.reservations.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations",
	//   "request": {
	//     "$ref": "Reservation"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.reservations.list":

type ReservationsListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: A list of all the reservations that have been configured for
// the specified project in specified zone. (== suppress_warning
// http-rest-shadowed ==)
func (r *ReservationsService) List(project string, zone string) *ReservationsListCall {
	c := &ReservationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ReservationsListCall) Filter(filter string) *ReservationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ReservationsListCall) MaxResults(maxResults int64) *ReservationsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ReservationsListCall) OrderBy(orderBy string) *ReservationsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ReservationsListCall) PageToken(pageToken string) *ReservationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsListCall) Fields(s ...googleapi.Field) *ReservationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReservationsListCall) IfNoneMatch(entityTag string) *ReservationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsListCall) Context(ctx context.Context) *ReservationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.list" call.
// Exactly one of *ReservationList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ReservationList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ReservationsListCall) Do(opts ...googleapi.CallOption) (*ReservationList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ReservationList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "A list of all the reservations that have been configured for the specified project in specified zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.reservations.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations",
	//   "response": {
	//     "$ref": "ReservationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ReservationsListCall) Pages(ctx context.Context, f func(*ReservationList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.reservations.resize":

type ReservationsResizeCall struct {
	s                         *Service
	project                   string
	zone                      string
	reservation               string
	reservationsresizerequest *ReservationsResizeRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Resize: Resizes the reservation (applicable to standalone
// reservations only). For more information, read Modifying
// reservations. (== suppress_warning http-rest-shadowed ==)
func (r *ReservationsService) Resize(project string, zone string, reservation string, reservationsresizerequest *ReservationsResizeRequest) *ReservationsResizeCall {
	c := &ReservationsResizeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.reservation = reservation
	c.reservationsresizerequest = reservationsresizerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ReservationsResizeCall) RequestId(requestId string) *ReservationsResizeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsResizeCall) Fields(s ...googleapi.Field) *ReservationsResizeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsResizeCall) Context(ctx context.Context) *ReservationsResizeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsResizeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsResizeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.reservationsresizerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations/{reservation}/resize")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":     c.project,
		"zone":        c.zone,
		"reservation": c.reservation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.resize" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReservationsResizeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Resizes the reservation (applicable to standalone reservations only). For more information, read Modifying reservations. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.reservations.resize",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "reservation"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "reservation": {
	//       "description": "Name of the reservation to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations/{reservation}/resize",
	//   "request": {
	//     "$ref": "ReservationsResizeRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.reservations.setIamPolicy":

type ReservationsSetIamPolicyCall struct {
	s                    *Service
	project              string
	zone                 string
	resource             string
	zonesetpolicyrequest *ZoneSetPolicyRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *ReservationsService) SetIamPolicy(project string, zone string, resource string, zonesetpolicyrequest *ZoneSetPolicyRequest) *ReservationsSetIamPolicyCall {
	c := &ReservationsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.zonesetpolicyrequest = zonesetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsSetIamPolicyCall) Fields(s ...googleapi.Field) *ReservationsSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsSetIamPolicyCall) Context(ctx context.Context) *ReservationsSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.zonesetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReservationsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.reservations.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "ZoneSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.reservations.testIamPermissions":

type ReservationsTestIamPermissionsCall struct {
	s                      *Service
	project                string
	zone                   string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *ReservationsService) TestIamPermissions(project string, zone string, resource string, testpermissionsrequest *TestPermissionsRequest) *ReservationsTestIamPermissionsCall {
	c := &ReservationsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReservationsTestIamPermissionsCall) Fields(s ...googleapi.Field) *ReservationsTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReservationsTestIamPermissionsCall) Context(ctx context.Context) *ReservationsTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReservationsTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReservationsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/reservations/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"zone":     c.zone,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.reservations.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ReservationsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.reservations.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "The name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/reservations/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.resourcePolicies.aggregatedList":

type ResourcePoliciesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of resource policies.
// (== suppress_warning http-rest-shadowed ==)
func (r *ResourcePoliciesService) AggregatedList(project string) *ResourcePoliciesAggregatedListCall {
	c := &ResourcePoliciesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ResourcePoliciesAggregatedListCall) Filter(filter string) *ResourcePoliciesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ResourcePoliciesAggregatedListCall) MaxResults(maxResults int64) *ResourcePoliciesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ResourcePoliciesAggregatedListCall) OrderBy(orderBy string) *ResourcePoliciesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ResourcePoliciesAggregatedListCall) PageToken(pageToken string) *ResourcePoliciesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesAggregatedListCall) Fields(s ...googleapi.Field) *ResourcePoliciesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ResourcePoliciesAggregatedListCall) IfNoneMatch(entityTag string) *ResourcePoliciesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesAggregatedListCall) Context(ctx context.Context) *ResourcePoliciesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/resourcePolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.aggregatedList" call.
// Exactly one of *ResourcePolicyAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ResourcePolicyAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ResourcePoliciesAggregatedListCall) Do(opts ...googleapi.CallOption) (*ResourcePolicyAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ResourcePolicyAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of resource policies. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.resourcePolicies.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/resourcePolicies",
	//   "response": {
	//     "$ref": "ResourcePolicyAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ResourcePoliciesAggregatedListCall) Pages(ctx context.Context, f func(*ResourcePolicyAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.resourcePolicies.delete":

type ResourcePoliciesDeleteCall struct {
	s              *Service
	project        string
	region         string
	resourcePolicy string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified resource policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *ResourcePoliciesService) Delete(project string, region string, resourcePolicy string) *ResourcePoliciesDeleteCall {
	c := &ResourcePoliciesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resourcePolicy = resourcePolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ResourcePoliciesDeleteCall) RequestId(requestId string) *ResourcePoliciesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesDeleteCall) Fields(s ...googleapi.Field) *ResourcePoliciesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesDeleteCall) Context(ctx context.Context) *ResourcePoliciesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/resourcePolicies/{resourcePolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"resourcePolicy": c.resourcePolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ResourcePoliciesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified resource policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.resourcePolicies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resourcePolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resourcePolicy": {
	//       "description": "Name of the resource policy to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/resourcePolicies/{resourcePolicy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.resourcePolicies.get":

type ResourcePoliciesGetCall struct {
	s              *Service
	project        string
	region         string
	resourcePolicy string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Retrieves all information of the specified resource policy. (==
// suppress_warning http-rest-shadowed ==)
func (r *ResourcePoliciesService) Get(project string, region string, resourcePolicy string) *ResourcePoliciesGetCall {
	c := &ResourcePoliciesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resourcePolicy = resourcePolicy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesGetCall) Fields(s ...googleapi.Field) *ResourcePoliciesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ResourcePoliciesGetCall) IfNoneMatch(entityTag string) *ResourcePoliciesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesGetCall) Context(ctx context.Context) *ResourcePoliciesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/resourcePolicies/{resourcePolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"region":         c.region,
		"resourcePolicy": c.resourcePolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.get" call.
// Exactly one of *ResourcePolicy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ResourcePolicy.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ResourcePoliciesGetCall) Do(opts ...googleapi.CallOption) (*ResourcePolicy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ResourcePolicy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves all information of the specified resource policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.resourcePolicies.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resourcePolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourcePolicy": {
	//       "description": "Name of the resource policy to retrieve.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/resourcePolicies/{resourcePolicy}",
	//   "response": {
	//     "$ref": "ResourcePolicy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.resourcePolicies.getIamPolicy":

type ResourcePoliciesGetIamPolicyCall struct {
	s            *Service
	project      string
	region       string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *ResourcePoliciesService) GetIamPolicy(project string, region string, resource string) *ResourcePoliciesGetIamPolicyCall {
	c := &ResourcePoliciesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesGetIamPolicyCall) Fields(s ...googleapi.Field) *ResourcePoliciesGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ResourcePoliciesGetIamPolicyCall) IfNoneMatch(entityTag string) *ResourcePoliciesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesGetIamPolicyCall) Context(ctx context.Context) *ResourcePoliciesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/resourcePolicies/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ResourcePoliciesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.resourcePolicies.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/resourcePolicies/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.resourcePolicies.insert":

type ResourcePoliciesInsertCall struct {
	s              *Service
	project        string
	region         string
	resourcepolicy *ResourcePolicy
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a new resource policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *ResourcePoliciesService) Insert(project string, region string, resourcepolicy *ResourcePolicy) *ResourcePoliciesInsertCall {
	c := &ResourcePoliciesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resourcepolicy = resourcepolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *ResourcePoliciesInsertCall) RequestId(requestId string) *ResourcePoliciesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesInsertCall) Fields(s ...googleapi.Field) *ResourcePoliciesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesInsertCall) Context(ctx context.Context) *ResourcePoliciesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.resourcepolicy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/resourcePolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ResourcePoliciesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new resource policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.resourcePolicies.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/resourcePolicies",
	//   "request": {
	//     "$ref": "ResourcePolicy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.resourcePolicies.list":

type ResourcePoliciesListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: A list all the resource policies that have been configured for
// the specified project in specified region. (== suppress_warning
// http-rest-shadowed ==)
func (r *ResourcePoliciesService) List(project string, region string) *ResourcePoliciesListCall {
	c := &ResourcePoliciesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ResourcePoliciesListCall) Filter(filter string) *ResourcePoliciesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ResourcePoliciesListCall) MaxResults(maxResults int64) *ResourcePoliciesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ResourcePoliciesListCall) OrderBy(orderBy string) *ResourcePoliciesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ResourcePoliciesListCall) PageToken(pageToken string) *ResourcePoliciesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesListCall) Fields(s ...googleapi.Field) *ResourcePoliciesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ResourcePoliciesListCall) IfNoneMatch(entityTag string) *ResourcePoliciesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesListCall) Context(ctx context.Context) *ResourcePoliciesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/resourcePolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.list" call.
// Exactly one of *ResourcePolicyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ResourcePolicyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ResourcePoliciesListCall) Do(opts ...googleapi.CallOption) (*ResourcePolicyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ResourcePolicyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "A list all the resource policies that have been configured for the specified project in specified region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.resourcePolicies.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/resourcePolicies",
	//   "response": {
	//     "$ref": "ResourcePolicyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ResourcePoliciesListCall) Pages(ctx context.Context, f func(*ResourcePolicyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.resourcePolicies.setIamPolicy":

type ResourcePoliciesSetIamPolicyCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	regionsetpolicyrequest *RegionSetPolicyRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *ResourcePoliciesService) SetIamPolicy(project string, region string, resource string, regionsetpolicyrequest *RegionSetPolicyRequest) *ResourcePoliciesSetIamPolicyCall {
	c := &ResourcePoliciesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.regionsetpolicyrequest = regionsetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesSetIamPolicyCall) Fields(s ...googleapi.Field) *ResourcePoliciesSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesSetIamPolicyCall) Context(ctx context.Context) *ResourcePoliciesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regionsetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/resourcePolicies/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ResourcePoliciesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.resourcePolicies.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/resourcePolicies/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "RegionSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.resourcePolicies.testIamPermissions":

type ResourcePoliciesTestIamPermissionsCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *ResourcePoliciesService) TestIamPermissions(project string, region string, resource string, testpermissionsrequest *TestPermissionsRequest) *ResourcePoliciesTestIamPermissionsCall {
	c := &ResourcePoliciesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ResourcePoliciesTestIamPermissionsCall) Fields(s ...googleapi.Field) *ResourcePoliciesTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ResourcePoliciesTestIamPermissionsCall) Context(ctx context.Context) *ResourcePoliciesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ResourcePoliciesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ResourcePoliciesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/resourcePolicies/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.resourcePolicies.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ResourcePoliciesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.resourcePolicies.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/resourcePolicies/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.routers.aggregatedList":

type RoutersAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of routers. (==
// suppress_warning http-rest-shadowed ==)
func (r *RoutersService) AggregatedList(project string) *RoutersAggregatedListCall {
	c := &RoutersAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RoutersAggregatedListCall) Filter(filter string) *RoutersAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RoutersAggregatedListCall) MaxResults(maxResults int64) *RoutersAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RoutersAggregatedListCall) OrderBy(orderBy string) *RoutersAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RoutersAggregatedListCall) PageToken(pageToken string) *RoutersAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersAggregatedListCall) Fields(s ...googleapi.Field) *RoutersAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RoutersAggregatedListCall) IfNoneMatch(entityTag string) *RoutersAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersAggregatedListCall) Context(ctx context.Context) *RoutersAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/routers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.aggregatedList" call.
// Exactly one of *RouterAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RouterAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RoutersAggregatedListCall) Do(opts ...googleapi.CallOption) (*RouterAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RouterAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of routers. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.routers.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/routers",
	//   "response": {
	//     "$ref": "RouterAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RoutersAggregatedListCall) Pages(ctx context.Context, f func(*RouterAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.routers.delete":

type RoutersDeleteCall struct {
	s          *Service
	project    string
	region     string
	router     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified Router resource. (== suppress_warning
// http-rest-shadowed ==)
func (r *RoutersService) Delete(project string, region string, router string) *RoutersDeleteCall {
	c := &RoutersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RoutersDeleteCall) RequestId(requestId string) *RoutersDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersDeleteCall) Fields(s ...googleapi.Field) *RoutersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersDeleteCall) Context(ctx context.Context) *RoutersDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers/{router}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"router":  c.router,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutersDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified Router resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.routers.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "router"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "router": {
	//       "description": "Name of the Router resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers/{router}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.routers.get":

type RoutersGetCall struct {
	s            *Service
	project      string
	region       string
	router       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified Router resource. Gets a list of available
// routers by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *RoutersService) Get(project string, region string, router string) *RoutersGetCall {
	c := &RoutersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersGetCall) Fields(s ...googleapi.Field) *RoutersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RoutersGetCall) IfNoneMatch(entityTag string) *RoutersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersGetCall) Context(ctx context.Context) *RoutersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers/{router}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"router":  c.router,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.get" call.
// Exactly one of *Router or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Router.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *RoutersGetCall) Do(opts ...googleapi.CallOption) (*Router, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Router{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified Router resource. Gets a list of available routers by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.routers.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "router"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "router": {
	//       "description": "Name of the Router resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers/{router}",
	//   "response": {
	//     "$ref": "Router"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.routers.getNatMappingInfo":

type RoutersGetNatMappingInfoCall struct {
	s            *Service
	project      string
	region       string
	router       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetNatMappingInfo: Retrieves runtime Nat mapping information of VM
// endpoints. (== suppress_warning http-rest-shadowed ==)
func (r *RoutersService) GetNatMappingInfo(project string, region string, router string) *RoutersGetNatMappingInfoCall {
	c := &RoutersGetNatMappingInfoCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RoutersGetNatMappingInfoCall) Filter(filter string) *RoutersGetNatMappingInfoCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RoutersGetNatMappingInfoCall) MaxResults(maxResults int64) *RoutersGetNatMappingInfoCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RoutersGetNatMappingInfoCall) OrderBy(orderBy string) *RoutersGetNatMappingInfoCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RoutersGetNatMappingInfoCall) PageToken(pageToken string) *RoutersGetNatMappingInfoCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersGetNatMappingInfoCall) Fields(s ...googleapi.Field) *RoutersGetNatMappingInfoCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RoutersGetNatMappingInfoCall) IfNoneMatch(entityTag string) *RoutersGetNatMappingInfoCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersGetNatMappingInfoCall) Context(ctx context.Context) *RoutersGetNatMappingInfoCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersGetNatMappingInfoCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersGetNatMappingInfoCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers/{router}/getNatMappingInfo")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"router":  c.router,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.getNatMappingInfo" call.
// Exactly one of *VmEndpointNatMappingsList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *VmEndpointNatMappingsList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RoutersGetNatMappingInfoCall) Do(opts ...googleapi.CallOption) (*VmEndpointNatMappingsList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VmEndpointNatMappingsList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves runtime Nat mapping information of VM endpoints. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.routers.getNatMappingInfo",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "router"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "router": {
	//       "description": "Name of the Router resource to query for Nat Mapping information of VM endpoints.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers/{router}/getNatMappingInfo",
	//   "response": {
	//     "$ref": "VmEndpointNatMappingsList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RoutersGetNatMappingInfoCall) Pages(ctx context.Context, f func(*VmEndpointNatMappingsList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.routers.getRouterStatus":

type RoutersGetRouterStatusCall struct {
	s            *Service
	project      string
	region       string
	router       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetRouterStatus: Retrieves runtime information of the specified
// router. (== suppress_warning http-rest-shadowed ==)
func (r *RoutersService) GetRouterStatus(project string, region string, router string) *RoutersGetRouterStatusCall {
	c := &RoutersGetRouterStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersGetRouterStatusCall) Fields(s ...googleapi.Field) *RoutersGetRouterStatusCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RoutersGetRouterStatusCall) IfNoneMatch(entityTag string) *RoutersGetRouterStatusCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersGetRouterStatusCall) Context(ctx context.Context) *RoutersGetRouterStatusCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersGetRouterStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersGetRouterStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers/{router}/getRouterStatus")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"router":  c.router,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.getRouterStatus" call.
// Exactly one of *RouterStatusResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RouterStatusResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RoutersGetRouterStatusCall) Do(opts ...googleapi.CallOption) (*RouterStatusResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RouterStatusResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves runtime information of the specified router. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.routers.getRouterStatus",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "router"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "router": {
	//       "description": "Name of the Router resource to query.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers/{router}/getRouterStatus",
	//   "response": {
	//     "$ref": "RouterStatusResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.routers.insert":

type RoutersInsertCall struct {
	s          *Service
	project    string
	region     string
	router     *Router
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a Router resource in the specified project and region
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *RoutersService) Insert(project string, region string, router *Router) *RoutersInsertCall {
	c := &RoutersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RoutersInsertCall) RequestId(requestId string) *RoutersInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersInsertCall) Fields(s ...googleapi.Field) *RoutersInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersInsertCall) Context(ctx context.Context) *RoutersInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.router)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutersInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a Router resource in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.routers.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers",
	//   "request": {
	//     "$ref": "Router"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.routers.list":

type RoutersListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of Router resources available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
func (r *RoutersService) List(project string, region string) *RoutersListCall {
	c := &RoutersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RoutersListCall) Filter(filter string) *RoutersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RoutersListCall) MaxResults(maxResults int64) *RoutersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RoutersListCall) OrderBy(orderBy string) *RoutersListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RoutersListCall) PageToken(pageToken string) *RoutersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersListCall) Fields(s ...googleapi.Field) *RoutersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RoutersListCall) IfNoneMatch(entityTag string) *RoutersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersListCall) Context(ctx context.Context) *RoutersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.list" call.
// Exactly one of *RouterList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RouterList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutersListCall) Do(opts ...googleapi.CallOption) (*RouterList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RouterList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of Router resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.routers.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers",
	//   "response": {
	//     "$ref": "RouterList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RoutersListCall) Pages(ctx context.Context, f func(*RouterList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.routers.patch":

type RoutersPatchCall struct {
	s          *Service
	project    string
	region     string
	router     string
	router2    *Router
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Patches the specified Router resource with the data included
// in the request. This method supports PATCH semantics and uses JSON
// merge patch format and processing rules. (== suppress_warning
// http-rest-shadowed ==)
func (r *RoutersService) Patch(project string, region string, router string, router2 *Router) *RoutersPatchCall {
	c := &RoutersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	c.router2 = router2
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RoutersPatchCall) RequestId(requestId string) *RoutersPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersPatchCall) Fields(s ...googleapi.Field) *RoutersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersPatchCall) Context(ctx context.Context) *RoutersPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.router2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers/{router}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"router":  c.router,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutersPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified Router resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.routers.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "router"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "router": {
	//       "description": "Name of the Router resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers/{router}",
	//   "request": {
	//     "$ref": "Router"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.routers.preview":

type RoutersPreviewCall struct {
	s          *Service
	project    string
	region     string
	router     string
	router2    *Router
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Preview: Preview fields auto-generated during router create and
// update operations. Calling this method does NOT create or update the
// router. (== suppress_warning http-rest-shadowed ==)
func (r *RoutersService) Preview(project string, region string, router string, router2 *Router) *RoutersPreviewCall {
	c := &RoutersPreviewCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	c.router2 = router2
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersPreviewCall) Fields(s ...googleapi.Field) *RoutersPreviewCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersPreviewCall) Context(ctx context.Context) *RoutersPreviewCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersPreviewCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersPreviewCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.router2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers/{router}/preview")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"router":  c.router,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.preview" call.
// Exactly one of *RoutersPreviewResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RoutersPreviewResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RoutersPreviewCall) Do(opts ...googleapi.CallOption) (*RoutersPreviewResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RoutersPreviewResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Preview fields auto-generated during router create and update operations. Calling this method does NOT create or update the router. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.routers.preview",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "router"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "router": {
	//       "description": "Name of the Router resource to query.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers/{router}/preview",
	//   "request": {
	//     "$ref": "Router"
	//   },
	//   "response": {
	//     "$ref": "RoutersPreviewResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.routers.update":

type RoutersUpdateCall struct {
	s          *Service
	project    string
	region     string
	router     string
	router2    *Router
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates the specified Router resource with the data included
// in the request. This method conforms to PUT semantics, which requests
// that the state of the target resource be created or replaced with the
// state defined by the representation enclosed in the request message
// payload. (== suppress_warning http-rest-shadowed ==)
func (r *RoutersService) Update(project string, region string, router string, router2 *Router) *RoutersUpdateCall {
	c := &RoutersUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.router = router
	c.router2 = router2
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RoutersUpdateCall) RequestId(requestId string) *RoutersUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutersUpdateCall) Fields(s ...googleapi.Field) *RoutersUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutersUpdateCall) Context(ctx context.Context) *RoutersUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutersUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutersUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.router2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/routers/{router}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
		"router":  c.router,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routers.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutersUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified Router resource with the data included in the request. This method conforms to PUT semantics, which requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.routers.update",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "router"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "router": {
	//       "description": "Name of the Router resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/routers/{router}",
	//   "request": {
	//     "$ref": "Router"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.routes.delete":

type RoutesDeleteCall struct {
	s          *Service
	project    string
	route      string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified Route resource. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/routes/delete
func (r *RoutesService) Delete(project string, route string) *RoutesDeleteCall {
	c := &RoutesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.route = route
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RoutesDeleteCall) RequestId(requestId string) *RoutesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutesDeleteCall) Fields(s ...googleapi.Field) *RoutesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutesDeleteCall) Context(ctx context.Context) *RoutesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes/{route}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"route":   c.route,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routes.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified Route resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.routes.delete",
	//   "parameterOrder": [
	//     "project",
	//     "route"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "route": {
	//       "description": "Name of the Route resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/routes/{route}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.routes.get":

type RoutesGetCall struct {
	s            *Service
	project      string
	route        string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified Route resource. Gets a list of available
// routes by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/routes/get
func (r *RoutesService) Get(project string, route string) *RoutesGetCall {
	c := &RoutesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.route = route
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutesGetCall) Fields(s ...googleapi.Field) *RoutesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RoutesGetCall) IfNoneMatch(entityTag string) *RoutesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutesGetCall) Context(ctx context.Context) *RoutesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes/{route}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"route":   c.route,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routes.get" call.
// Exactly one of *Route or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Route.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *RoutesGetCall) Do(opts ...googleapi.CallOption) (*Route, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Route{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified Route resource. Gets a list of available routes by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.routes.get",
	//   "parameterOrder": [
	//     "project",
	//     "route"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "route": {
	//       "description": "Name of the Route resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/routes/{route}",
	//   "response": {
	//     "$ref": "Route"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.routes.insert":

type RoutesInsertCall struct {
	s          *Service
	project    string
	route      *Route
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a Route resource in the specified project using the
// data included in the request. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/routes/insert
func (r *RoutesService) Insert(project string, route *Route) *RoutesInsertCall {
	c := &RoutesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.route = route
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *RoutesInsertCall) RequestId(requestId string) *RoutesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutesInsertCall) Fields(s ...googleapi.Field) *RoutesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutesInsertCall) Context(ctx context.Context) *RoutesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.route)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routes.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a Route resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.routes.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/routes",
	//   "request": {
	//     "$ref": "Route"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.routes.list":

type RoutesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of Route resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/routes/list
func (r *RoutesService) List(project string) *RoutesListCall {
	c := &RoutesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *RoutesListCall) Filter(filter string) *RoutesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *RoutesListCall) MaxResults(maxResults int64) *RoutesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *RoutesListCall) OrderBy(orderBy string) *RoutesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *RoutesListCall) PageToken(pageToken string) *RoutesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RoutesListCall) Fields(s ...googleapi.Field) *RoutesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RoutesListCall) IfNoneMatch(entityTag string) *RoutesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RoutesListCall) Context(ctx context.Context) *RoutesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RoutesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.routes.list" call.
// Exactly one of *RouteList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RouteList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *RoutesListCall) Do(opts ...googleapi.CallOption) (*RouteList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RouteList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of Route resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.routes.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/routes",
	//   "response": {
	//     "$ref": "RouteList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *RoutesListCall) Pages(ctx context.Context, f func(*RouteList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.securityPolicies.addRule":

type SecurityPoliciesAddRuleCall struct {
	s                  *Service
	project            string
	securityPolicy     string
	securitypolicyrule *SecurityPolicyRule
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// AddRule: Inserts a rule into a security policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *SecurityPoliciesService) AddRule(project string, securityPolicy string, securitypolicyrule *SecurityPolicyRule) *SecurityPoliciesAddRuleCall {
	c := &SecurityPoliciesAddRuleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securityPolicy = securityPolicy
	c.securitypolicyrule = securitypolicyrule
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesAddRuleCall) Fields(s ...googleapi.Field) *SecurityPoliciesAddRuleCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesAddRuleCall) Context(ctx context.Context) *SecurityPoliciesAddRuleCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesAddRuleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesAddRuleCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.securitypolicyrule)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies/{securityPolicy}/addRule")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"securityPolicy": c.securityPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.addRule" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SecurityPoliciesAddRuleCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a rule into a security policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.securityPolicies.addRule",
	//   "parameterOrder": [
	//     "project",
	//     "securityPolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "securityPolicy": {
	//       "description": "Name of the security policy to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies/{securityPolicy}/addRule",
	//   "request": {
	//     "$ref": "SecurityPolicyRule"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.securityPolicies.delete":

type SecurityPoliciesDeleteCall struct {
	s              *Service
	project        string
	securityPolicy string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *SecurityPoliciesService) Delete(project string, securityPolicy string) *SecurityPoliciesDeleteCall {
	c := &SecurityPoliciesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securityPolicy = securityPolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SecurityPoliciesDeleteCall) RequestId(requestId string) *SecurityPoliciesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesDeleteCall) Fields(s ...googleapi.Field) *SecurityPoliciesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesDeleteCall) Context(ctx context.Context) *SecurityPoliciesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies/{securityPolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"securityPolicy": c.securityPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SecurityPoliciesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.securityPolicies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "securityPolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "securityPolicy": {
	//       "description": "Name of the security policy to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies/{securityPolicy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.securityPolicies.get":

type SecurityPoliciesGetCall struct {
	s              *Service
	project        string
	securityPolicy string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: List all of the ordered rules present in a single specified
// policy. (== suppress_warning http-rest-shadowed ==)
func (r *SecurityPoliciesService) Get(project string, securityPolicy string) *SecurityPoliciesGetCall {
	c := &SecurityPoliciesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securityPolicy = securityPolicy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesGetCall) Fields(s ...googleapi.Field) *SecurityPoliciesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SecurityPoliciesGetCall) IfNoneMatch(entityTag string) *SecurityPoliciesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesGetCall) Context(ctx context.Context) *SecurityPoliciesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies/{securityPolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"securityPolicy": c.securityPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.get" call.
// Exactly one of *SecurityPolicy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SecurityPolicy.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SecurityPoliciesGetCall) Do(opts ...googleapi.CallOption) (*SecurityPolicy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SecurityPolicy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List all of the ordered rules present in a single specified policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.securityPolicies.get",
	//   "parameterOrder": [
	//     "project",
	//     "securityPolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "securityPolicy": {
	//       "description": "Name of the security policy to get.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies/{securityPolicy}",
	//   "response": {
	//     "$ref": "SecurityPolicy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.securityPolicies.getRule":

type SecurityPoliciesGetRuleCall struct {
	s              *Service
	project        string
	securityPolicy string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// GetRule: Gets a rule at the specified priority. (== suppress_warning
// http-rest-shadowed ==)
func (r *SecurityPoliciesService) GetRule(project string, securityPolicy string) *SecurityPoliciesGetRuleCall {
	c := &SecurityPoliciesGetRuleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securityPolicy = securityPolicy
	return c
}

// Priority sets the optional parameter "priority": The priority of the
// rule to get from the security policy.
func (c *SecurityPoliciesGetRuleCall) Priority(priority int64) *SecurityPoliciesGetRuleCall {
	c.urlParams_.Set("priority", fmt.Sprint(priority))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesGetRuleCall) Fields(s ...googleapi.Field) *SecurityPoliciesGetRuleCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SecurityPoliciesGetRuleCall) IfNoneMatch(entityTag string) *SecurityPoliciesGetRuleCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesGetRuleCall) Context(ctx context.Context) *SecurityPoliciesGetRuleCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesGetRuleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesGetRuleCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies/{securityPolicy}/getRule")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"securityPolicy": c.securityPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.getRule" call.
// Exactly one of *SecurityPolicyRule or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SecurityPolicyRule.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SecurityPoliciesGetRuleCall) Do(opts ...googleapi.CallOption) (*SecurityPolicyRule, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SecurityPolicyRule{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a rule at the specified priority. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.securityPolicies.getRule",
	//   "parameterOrder": [
	//     "project",
	//     "securityPolicy"
	//   ],
	//   "parameters": {
	//     "priority": {
	//       "description": "The priority of the rule to get from the security policy.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "securityPolicy": {
	//       "description": "Name of the security policy to which the queried rule belongs.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies/{securityPolicy}/getRule",
	//   "response": {
	//     "$ref": "SecurityPolicyRule"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.securityPolicies.insert":

type SecurityPoliciesInsertCall struct {
	s              *Service
	project        string
	securitypolicy *SecurityPolicy
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a new policy in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *SecurityPoliciesService) Insert(project string, securitypolicy *SecurityPolicy) *SecurityPoliciesInsertCall {
	c := &SecurityPoliciesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securitypolicy = securitypolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SecurityPoliciesInsertCall) RequestId(requestId string) *SecurityPoliciesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesInsertCall) Fields(s ...googleapi.Field) *SecurityPoliciesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesInsertCall) Context(ctx context.Context) *SecurityPoliciesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.securitypolicy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SecurityPoliciesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new policy in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.securityPolicies.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies",
	//   "request": {
	//     "$ref": "SecurityPolicy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.securityPolicies.list":

type SecurityPoliciesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List all the policies that have been configured for the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *SecurityPoliciesService) List(project string) *SecurityPoliciesListCall {
	c := &SecurityPoliciesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SecurityPoliciesListCall) Filter(filter string) *SecurityPoliciesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SecurityPoliciesListCall) MaxResults(maxResults int64) *SecurityPoliciesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SecurityPoliciesListCall) OrderBy(orderBy string) *SecurityPoliciesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SecurityPoliciesListCall) PageToken(pageToken string) *SecurityPoliciesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesListCall) Fields(s ...googleapi.Field) *SecurityPoliciesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SecurityPoliciesListCall) IfNoneMatch(entityTag string) *SecurityPoliciesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesListCall) Context(ctx context.Context) *SecurityPoliciesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.list" call.
// Exactly one of *SecurityPolicyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SecurityPolicyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SecurityPoliciesListCall) Do(opts ...googleapi.CallOption) (*SecurityPolicyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SecurityPolicyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List all the policies that have been configured for the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.securityPolicies.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies",
	//   "response": {
	//     "$ref": "SecurityPolicyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SecurityPoliciesListCall) Pages(ctx context.Context, f func(*SecurityPolicyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.securityPolicies.patch":

type SecurityPoliciesPatchCall struct {
	s              *Service
	project        string
	securityPolicy string
	securitypolicy *SecurityPolicy
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Patch: Patches the specified policy with the data included in the
// request. (== suppress_warning http-rest-shadowed ==)
func (r *SecurityPoliciesService) Patch(project string, securityPolicy string, securitypolicy *SecurityPolicy) *SecurityPoliciesPatchCall {
	c := &SecurityPoliciesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securityPolicy = securityPolicy
	c.securitypolicy = securitypolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SecurityPoliciesPatchCall) RequestId(requestId string) *SecurityPoliciesPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesPatchCall) Fields(s ...googleapi.Field) *SecurityPoliciesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesPatchCall) Context(ctx context.Context) *SecurityPoliciesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.securitypolicy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies/{securityPolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"securityPolicy": c.securityPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SecurityPoliciesPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified policy with the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.securityPolicies.patch",
	//   "parameterOrder": [
	//     "project",
	//     "securityPolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "securityPolicy": {
	//       "description": "Name of the security policy to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies/{securityPolicy}",
	//   "request": {
	//     "$ref": "SecurityPolicy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.securityPolicies.patchRule":

type SecurityPoliciesPatchRuleCall struct {
	s                  *Service
	project            string
	securityPolicy     string
	securitypolicyrule *SecurityPolicyRule
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// PatchRule: Patches a rule at the specified priority. (==
// suppress_warning http-rest-shadowed ==)
func (r *SecurityPoliciesService) PatchRule(project string, securityPolicy string, securitypolicyrule *SecurityPolicyRule) *SecurityPoliciesPatchRuleCall {
	c := &SecurityPoliciesPatchRuleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securityPolicy = securityPolicy
	c.securitypolicyrule = securitypolicyrule
	return c
}

// Priority sets the optional parameter "priority": The priority of the
// rule to patch.
func (c *SecurityPoliciesPatchRuleCall) Priority(priority int64) *SecurityPoliciesPatchRuleCall {
	c.urlParams_.Set("priority", fmt.Sprint(priority))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesPatchRuleCall) Fields(s ...googleapi.Field) *SecurityPoliciesPatchRuleCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesPatchRuleCall) Context(ctx context.Context) *SecurityPoliciesPatchRuleCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesPatchRuleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesPatchRuleCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.securitypolicyrule)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies/{securityPolicy}/patchRule")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"securityPolicy": c.securityPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.patchRule" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SecurityPoliciesPatchRuleCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches a rule at the specified priority. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.securityPolicies.patchRule",
	//   "parameterOrder": [
	//     "project",
	//     "securityPolicy"
	//   ],
	//   "parameters": {
	//     "priority": {
	//       "description": "The priority of the rule to patch.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "securityPolicy": {
	//       "description": "Name of the security policy to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies/{securityPolicy}/patchRule",
	//   "request": {
	//     "$ref": "SecurityPolicyRule"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.securityPolicies.removeRule":

type SecurityPoliciesRemoveRuleCall struct {
	s              *Service
	project        string
	securityPolicy string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// RemoveRule: Deletes a rule at the specified priority. (==
// suppress_warning http-rest-shadowed ==)
func (r *SecurityPoliciesService) RemoveRule(project string, securityPolicy string) *SecurityPoliciesRemoveRuleCall {
	c := &SecurityPoliciesRemoveRuleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.securityPolicy = securityPolicy
	return c
}

// Priority sets the optional parameter "priority": The priority of the
// rule to remove from the security policy.
func (c *SecurityPoliciesRemoveRuleCall) Priority(priority int64) *SecurityPoliciesRemoveRuleCall {
	c.urlParams_.Set("priority", fmt.Sprint(priority))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SecurityPoliciesRemoveRuleCall) Fields(s ...googleapi.Field) *SecurityPoliciesRemoveRuleCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SecurityPoliciesRemoveRuleCall) Context(ctx context.Context) *SecurityPoliciesRemoveRuleCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SecurityPoliciesRemoveRuleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SecurityPoliciesRemoveRuleCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/securityPolicies/{securityPolicy}/removeRule")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"securityPolicy": c.securityPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.securityPolicies.removeRule" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SecurityPoliciesRemoveRuleCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a rule at the specified priority. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.securityPolicies.removeRule",
	//   "parameterOrder": [
	//     "project",
	//     "securityPolicy"
	//   ],
	//   "parameters": {
	//     "priority": {
	//       "description": "The priority of the rule to remove from the security policy.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "securityPolicy": {
	//       "description": "Name of the security policy to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/securityPolicies/{securityPolicy}/removeRule",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.snapshots.delete":

type SnapshotsDeleteCall struct {
	s          *Service
	project    string
	snapshot   string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified Snapshot resource. Keep in mind that
// deleting a single snapshot might not necessarily delete all the data
// on that snapshot. If any data on the snapshot that is marked for
// deletion is needed for subsequent snapshots, the data will be moved
// to the next corresponding snapshot.
//
// For more information, see Deleting snapshots. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/snapshots/delete
func (r *SnapshotsService) Delete(project string, snapshot string) *SnapshotsDeleteCall {
	c := &SnapshotsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.snapshot = snapshot
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SnapshotsDeleteCall) RequestId(requestId string) *SnapshotsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SnapshotsDeleteCall) Fields(s ...googleapi.Field) *SnapshotsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SnapshotsDeleteCall) Context(ctx context.Context) *SnapshotsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SnapshotsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SnapshotsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{snapshot}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"snapshot": c.snapshot,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.snapshots.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SnapshotsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified Snapshot resource. Keep in mind that deleting a single snapshot might not necessarily delete all the data on that snapshot. If any data on the snapshot that is marked for deletion is needed for subsequent snapshots, the data will be moved to the next corresponding snapshot.\n\nFor more information, see Deleting snapshots. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.snapshots.delete",
	//   "parameterOrder": [
	//     "project",
	//     "snapshot"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "snapshot": {
	//       "description": "Name of the Snapshot resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/snapshots/{snapshot}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.snapshots.get":

type SnapshotsGetCall struct {
	s            *Service
	project      string
	snapshot     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified Snapshot resource. Gets a list of
// available snapshots by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/snapshots/get
func (r *SnapshotsService) Get(project string, snapshot string) *SnapshotsGetCall {
	c := &SnapshotsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.snapshot = snapshot
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SnapshotsGetCall) Fields(s ...googleapi.Field) *SnapshotsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SnapshotsGetCall) IfNoneMatch(entityTag string) *SnapshotsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SnapshotsGetCall) Context(ctx context.Context) *SnapshotsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SnapshotsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SnapshotsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{snapshot}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"snapshot": c.snapshot,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.snapshots.get" call.
// Exactly one of *Snapshot or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Snapshot.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SnapshotsGetCall) Do(opts ...googleapi.CallOption) (*Snapshot, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Snapshot{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified Snapshot resource. Gets a list of available snapshots by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.snapshots.get",
	//   "parameterOrder": [
	//     "project",
	//     "snapshot"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "snapshot": {
	//       "description": "Name of the Snapshot resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/snapshots/{snapshot}",
	//   "response": {
	//     "$ref": "Snapshot"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.snapshots.getIamPolicy":

type SnapshotsGetIamPolicyCall struct {
	s            *Service
	project      string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *SnapshotsService) GetIamPolicy(project string, resource string) *SnapshotsGetIamPolicyCall {
	c := &SnapshotsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SnapshotsGetIamPolicyCall) Fields(s ...googleapi.Field) *SnapshotsGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SnapshotsGetIamPolicyCall) IfNoneMatch(entityTag string) *SnapshotsGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SnapshotsGetIamPolicyCall) Context(ctx context.Context) *SnapshotsGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SnapshotsGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SnapshotsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.snapshots.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *SnapshotsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.snapshots.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/snapshots/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.snapshots.list":

type SnapshotsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of Snapshot resources contained within the
// specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/snapshots/list
func (r *SnapshotsService) List(project string) *SnapshotsListCall {
	c := &SnapshotsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SnapshotsListCall) Filter(filter string) *SnapshotsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SnapshotsListCall) MaxResults(maxResults int64) *SnapshotsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SnapshotsListCall) OrderBy(orderBy string) *SnapshotsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SnapshotsListCall) PageToken(pageToken string) *SnapshotsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SnapshotsListCall) Fields(s ...googleapi.Field) *SnapshotsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SnapshotsListCall) IfNoneMatch(entityTag string) *SnapshotsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SnapshotsListCall) Context(ctx context.Context) *SnapshotsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SnapshotsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SnapshotsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.snapshots.list" call.
// Exactly one of *SnapshotList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SnapshotList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SnapshotsListCall) Do(opts ...googleapi.CallOption) (*SnapshotList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SnapshotList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of Snapshot resources contained within the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.snapshots.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/snapshots",
	//   "response": {
	//     "$ref": "SnapshotList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SnapshotsListCall) Pages(ctx context.Context, f func(*SnapshotList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.snapshots.setIamPolicy":

type SnapshotsSetIamPolicyCall struct {
	s                      *Service
	project                string
	resource               string
	globalsetpolicyrequest *GlobalSetPolicyRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *SnapshotsService) SetIamPolicy(project string, resource string, globalsetpolicyrequest *GlobalSetPolicyRequest) *SnapshotsSetIamPolicyCall {
	c := &SnapshotsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.globalsetpolicyrequest = globalsetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SnapshotsSetIamPolicyCall) Fields(s ...googleapi.Field) *SnapshotsSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SnapshotsSetIamPolicyCall) Context(ctx context.Context) *SnapshotsSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SnapshotsSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SnapshotsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.globalsetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.snapshots.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *SnapshotsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.snapshots.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/snapshots/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "GlobalSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.snapshots.setLabels":

type SnapshotsSetLabelsCall struct {
	s                      *Service
	project                string
	resource               string
	globalsetlabelsrequest *GlobalSetLabelsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetLabels: Sets the labels on a snapshot. To learn more about labels,
// read the Labeling Resources documentation. (== suppress_warning
// http-rest-shadowed ==)
func (r *SnapshotsService) SetLabels(project string, resource string, globalsetlabelsrequest *GlobalSetLabelsRequest) *SnapshotsSetLabelsCall {
	c := &SnapshotsSetLabelsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.globalsetlabelsrequest = globalsetlabelsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SnapshotsSetLabelsCall) Fields(s ...googleapi.Field) *SnapshotsSetLabelsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SnapshotsSetLabelsCall) Context(ctx context.Context) *SnapshotsSetLabelsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SnapshotsSetLabelsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SnapshotsSetLabelsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.globalsetlabelsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{resource}/setLabels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.snapshots.setLabels" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SnapshotsSetLabelsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the labels on a snapshot. To learn more about labels, read the Labeling Resources documentation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.snapshots.setLabels",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/snapshots/{resource}/setLabels",
	//   "request": {
	//     "$ref": "GlobalSetLabelsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.snapshots.testIamPermissions":

type SnapshotsTestIamPermissionsCall struct {
	s                      *Service
	project                string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *SnapshotsService) TestIamPermissions(project string, resource string, testpermissionsrequest *TestPermissionsRequest) *SnapshotsTestIamPermissionsCall {
	c := &SnapshotsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SnapshotsTestIamPermissionsCall) Fields(s ...googleapi.Field) *SnapshotsTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SnapshotsTestIamPermissionsCall) Context(ctx context.Context) *SnapshotsTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SnapshotsTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SnapshotsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.snapshots.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SnapshotsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.snapshots.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9_]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/snapshots/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.sslCertificates.aggregatedList":

type SslCertificatesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of all SslCertificate resources,
// regional and global, available to the specified project. (==
// suppress_warning http-rest-shadowed ==)
func (r *SslCertificatesService) AggregatedList(project string) *SslCertificatesAggregatedListCall {
	c := &SslCertificatesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SslCertificatesAggregatedListCall) Filter(filter string) *SslCertificatesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SslCertificatesAggregatedListCall) MaxResults(maxResults int64) *SslCertificatesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SslCertificatesAggregatedListCall) OrderBy(orderBy string) *SslCertificatesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SslCertificatesAggregatedListCall) PageToken(pageToken string) *SslCertificatesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslCertificatesAggregatedListCall) Fields(s ...googleapi.Field) *SslCertificatesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SslCertificatesAggregatedListCall) IfNoneMatch(entityTag string) *SslCertificatesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslCertificatesAggregatedListCall) Context(ctx context.Context) *SslCertificatesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslCertificatesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslCertificatesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/sslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslCertificates.aggregatedList" call.
// Exactly one of *SslCertificateAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *SslCertificateAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SslCertificatesAggregatedListCall) Do(opts ...googleapi.CallOption) (*SslCertificateAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslCertificateAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of all SslCertificate resources, regional and global, available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.sslCertificates.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Name of the project scoping this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/sslCertificates",
	//   "response": {
	//     "$ref": "SslCertificateAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SslCertificatesAggregatedListCall) Pages(ctx context.Context, f func(*SslCertificateAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.sslCertificates.delete":

type SslCertificatesDeleteCall struct {
	s              *Service
	project        string
	sslCertificate string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified SslCertificate resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *SslCertificatesService) Delete(project string, sslCertificate string) *SslCertificatesDeleteCall {
	c := &SslCertificatesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.sslCertificate = sslCertificate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SslCertificatesDeleteCall) RequestId(requestId string) *SslCertificatesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslCertificatesDeleteCall) Fields(s ...googleapi.Field) *SslCertificatesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslCertificatesDeleteCall) Context(ctx context.Context) *SslCertificatesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslCertificatesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslCertificatesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslCertificates/{sslCertificate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"sslCertificate": c.sslCertificate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslCertificates.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SslCertificatesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified SslCertificate resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.sslCertificates.delete",
	//   "parameterOrder": [
	//     "project",
	//     "sslCertificate"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sslCertificate": {
	//       "description": "Name of the SslCertificate resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslCertificates/{sslCertificate}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.sslCertificates.get":

type SslCertificatesGetCall struct {
	s              *Service
	project        string
	sslCertificate string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified SslCertificate resource. Gets a list of
// available SSL certificates by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *SslCertificatesService) Get(project string, sslCertificate string) *SslCertificatesGetCall {
	c := &SslCertificatesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.sslCertificate = sslCertificate
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslCertificatesGetCall) Fields(s ...googleapi.Field) *SslCertificatesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SslCertificatesGetCall) IfNoneMatch(entityTag string) *SslCertificatesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslCertificatesGetCall) Context(ctx context.Context) *SslCertificatesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslCertificatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslCertificatesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslCertificates/{sslCertificate}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"sslCertificate": c.sslCertificate,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslCertificates.get" call.
// Exactly one of *SslCertificate or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SslCertificate.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SslCertificatesGetCall) Do(opts ...googleapi.CallOption) (*SslCertificate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslCertificate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified SslCertificate resource. Gets a list of available SSL certificates by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.sslCertificates.get",
	//   "parameterOrder": [
	//     "project",
	//     "sslCertificate"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sslCertificate": {
	//       "description": "Name of the SslCertificate resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslCertificates/{sslCertificate}",
	//   "response": {
	//     "$ref": "SslCertificate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.sslCertificates.insert":

type SslCertificatesInsertCall struct {
	s              *Service
	project        string
	sslcertificate *SslCertificate
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a SslCertificate resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *SslCertificatesService) Insert(project string, sslcertificate *SslCertificate) *SslCertificatesInsertCall {
	c := &SslCertificatesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.sslcertificate = sslcertificate
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SslCertificatesInsertCall) RequestId(requestId string) *SslCertificatesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslCertificatesInsertCall) Fields(s ...googleapi.Field) *SslCertificatesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslCertificatesInsertCall) Context(ctx context.Context) *SslCertificatesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslCertificatesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslCertificatesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.sslcertificate)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslCertificates.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SslCertificatesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a SslCertificate resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.sslCertificates.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslCertificates",
	//   "request": {
	//     "$ref": "SslCertificate"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.sslCertificates.list":

type SslCertificatesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of SslCertificate resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *SslCertificatesService) List(project string) *SslCertificatesListCall {
	c := &SslCertificatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SslCertificatesListCall) Filter(filter string) *SslCertificatesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SslCertificatesListCall) MaxResults(maxResults int64) *SslCertificatesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SslCertificatesListCall) OrderBy(orderBy string) *SslCertificatesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SslCertificatesListCall) PageToken(pageToken string) *SslCertificatesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslCertificatesListCall) Fields(s ...googleapi.Field) *SslCertificatesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SslCertificatesListCall) IfNoneMatch(entityTag string) *SslCertificatesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslCertificatesListCall) Context(ctx context.Context) *SslCertificatesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslCertificatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslCertificatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslCertificates.list" call.
// Exactly one of *SslCertificateList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SslCertificateList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SslCertificatesListCall) Do(opts ...googleapi.CallOption) (*SslCertificateList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslCertificateList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of SslCertificate resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.sslCertificates.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslCertificates",
	//   "response": {
	//     "$ref": "SslCertificateList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SslCertificatesListCall) Pages(ctx context.Context, f func(*SslCertificateList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.sslPolicies.delete":

type SslPoliciesDeleteCall struct {
	s          *Service
	project    string
	sslPolicy  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified SSL policy. The SSL policy resource can
// be deleted only if it is not in use by any TargetHttpsProxy or
// TargetSslProxy resources. (== suppress_warning http-rest-shadowed ==)
func (r *SslPoliciesService) Delete(project string, sslPolicy string) *SslPoliciesDeleteCall {
	c := &SslPoliciesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.sslPolicy = sslPolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SslPoliciesDeleteCall) RequestId(requestId string) *SslPoliciesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslPoliciesDeleteCall) Fields(s ...googleapi.Field) *SslPoliciesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslPoliciesDeleteCall) Context(ctx context.Context) *SslPoliciesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslPoliciesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslPoliciesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslPolicies/{sslPolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"sslPolicy": c.sslPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslPolicies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SslPoliciesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified SSL policy. The SSL policy resource can be deleted only if it is not in use by any TargetHttpsProxy or TargetSslProxy resources. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.sslPolicies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "sslPolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sslPolicy": {
	//       "description": "Name of the SSL policy to delete. The name must be 1-63 characters long, and comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslPolicies/{sslPolicy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.sslPolicies.get":

type SslPoliciesGetCall struct {
	s            *Service
	project      string
	sslPolicy    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Lists all of the ordered rules present in a single specified
// policy. (== suppress_warning http-rest-shadowed ==)
func (r *SslPoliciesService) Get(project string, sslPolicy string) *SslPoliciesGetCall {
	c := &SslPoliciesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.sslPolicy = sslPolicy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslPoliciesGetCall) Fields(s ...googleapi.Field) *SslPoliciesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SslPoliciesGetCall) IfNoneMatch(entityTag string) *SslPoliciesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslPoliciesGetCall) Context(ctx context.Context) *SslPoliciesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslPoliciesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslPoliciesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslPolicies/{sslPolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"sslPolicy": c.sslPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslPolicies.get" call.
// Exactly one of *SslPolicy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SslPolicy.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SslPoliciesGetCall) Do(opts ...googleapi.CallOption) (*SslPolicy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslPolicy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists all of the ordered rules present in a single specified policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.sslPolicies.get",
	//   "parameterOrder": [
	//     "project",
	//     "sslPolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sslPolicy": {
	//       "description": "Name of the SSL policy to update. The name must be 1-63 characters long, and comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslPolicies/{sslPolicy}",
	//   "response": {
	//     "$ref": "SslPolicy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.sslPolicies.insert":

type SslPoliciesInsertCall struct {
	s          *Service
	project    string
	sslpolicy  *SslPolicy
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Returns the specified SSL policy resource. Gets a list of
// available SSL policies by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *SslPoliciesService) Insert(project string, sslpolicy *SslPolicy) *SslPoliciesInsertCall {
	c := &SslPoliciesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.sslpolicy = sslpolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SslPoliciesInsertCall) RequestId(requestId string) *SslPoliciesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslPoliciesInsertCall) Fields(s ...googleapi.Field) *SslPoliciesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslPoliciesInsertCall) Context(ctx context.Context) *SslPoliciesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslPoliciesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslPoliciesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.sslpolicy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslPolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslPolicies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SslPoliciesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified SSL policy resource. Gets a list of available SSL policies by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.sslPolicies.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslPolicies",
	//   "request": {
	//     "$ref": "SslPolicy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.sslPolicies.list":

type SslPoliciesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all the SSL policies that have been configured for the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *SslPoliciesService) List(project string) *SslPoliciesListCall {
	c := &SslPoliciesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SslPoliciesListCall) Filter(filter string) *SslPoliciesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SslPoliciesListCall) MaxResults(maxResults int64) *SslPoliciesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SslPoliciesListCall) OrderBy(orderBy string) *SslPoliciesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SslPoliciesListCall) PageToken(pageToken string) *SslPoliciesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslPoliciesListCall) Fields(s ...googleapi.Field) *SslPoliciesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SslPoliciesListCall) IfNoneMatch(entityTag string) *SslPoliciesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslPoliciesListCall) Context(ctx context.Context) *SslPoliciesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslPoliciesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslPoliciesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslPolicies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslPolicies.list" call.
// Exactly one of *SslPoliciesList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SslPoliciesList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SslPoliciesListCall) Do(opts ...googleapi.CallOption) (*SslPoliciesList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslPoliciesList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists all the SSL policies that have been configured for the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.sslPolicies.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslPolicies",
	//   "response": {
	//     "$ref": "SslPoliciesList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SslPoliciesListCall) Pages(ctx context.Context, f func(*SslPoliciesList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.sslPolicies.listAvailableFeatures":

type SslPoliciesListAvailableFeaturesCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListAvailableFeatures: Lists all features that can be specified in
// the SSL policy when using custom profile. (== suppress_warning
// http-rest-shadowed ==)
func (r *SslPoliciesService) ListAvailableFeatures(project string) *SslPoliciesListAvailableFeaturesCall {
	c := &SslPoliciesListAvailableFeaturesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SslPoliciesListAvailableFeaturesCall) Filter(filter string) *SslPoliciesListAvailableFeaturesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SslPoliciesListAvailableFeaturesCall) MaxResults(maxResults int64) *SslPoliciesListAvailableFeaturesCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SslPoliciesListAvailableFeaturesCall) OrderBy(orderBy string) *SslPoliciesListAvailableFeaturesCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SslPoliciesListAvailableFeaturesCall) PageToken(pageToken string) *SslPoliciesListAvailableFeaturesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslPoliciesListAvailableFeaturesCall) Fields(s ...googleapi.Field) *SslPoliciesListAvailableFeaturesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SslPoliciesListAvailableFeaturesCall) IfNoneMatch(entityTag string) *SslPoliciesListAvailableFeaturesCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslPoliciesListAvailableFeaturesCall) Context(ctx context.Context) *SslPoliciesListAvailableFeaturesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslPoliciesListAvailableFeaturesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslPoliciesListAvailableFeaturesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslPolicies/listAvailableFeatures")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslPolicies.listAvailableFeatures" call.
// Exactly one of *SslPoliciesListAvailableFeaturesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *SslPoliciesListAvailableFeaturesResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SslPoliciesListAvailableFeaturesCall) Do(opts ...googleapi.CallOption) (*SslPoliciesListAvailableFeaturesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SslPoliciesListAvailableFeaturesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists all features that can be specified in the SSL policy when using custom profile. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.sslPolicies.listAvailableFeatures",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslPolicies/listAvailableFeatures",
	//   "response": {
	//     "$ref": "SslPoliciesListAvailableFeaturesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.sslPolicies.patch":

type SslPoliciesPatchCall struct {
	s          *Service
	project    string
	sslPolicy  string
	sslpolicy  *SslPolicy
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Patches the specified SSL policy with the data included in the
// request. (== suppress_warning http-rest-shadowed ==)
func (r *SslPoliciesService) Patch(project string, sslPolicy string, sslpolicy *SslPolicy) *SslPoliciesPatchCall {
	c := &SslPoliciesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.sslPolicy = sslPolicy
	c.sslpolicy = sslpolicy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SslPoliciesPatchCall) RequestId(requestId string) *SslPoliciesPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SslPoliciesPatchCall) Fields(s ...googleapi.Field) *SslPoliciesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SslPoliciesPatchCall) Context(ctx context.Context) *SslPoliciesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SslPoliciesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SslPoliciesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.sslpolicy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/sslPolicies/{sslPolicy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"sslPolicy": c.sslPolicy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.sslPolicies.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SslPoliciesPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified SSL policy with the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.sslPolicies.patch",
	//   "parameterOrder": [
	//     "project",
	//     "sslPolicy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sslPolicy": {
	//       "description": "Name of the SSL policy to update. The name must be 1-63 characters long, and comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/sslPolicies/{sslPolicy}",
	//   "request": {
	//     "$ref": "SslPolicy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.subnetworks.aggregatedList":

type SubnetworksAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of subnetworks. (==
// suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) AggregatedList(project string) *SubnetworksAggregatedListCall {
	c := &SubnetworksAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SubnetworksAggregatedListCall) Filter(filter string) *SubnetworksAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SubnetworksAggregatedListCall) MaxResults(maxResults int64) *SubnetworksAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SubnetworksAggregatedListCall) OrderBy(orderBy string) *SubnetworksAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SubnetworksAggregatedListCall) PageToken(pageToken string) *SubnetworksAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksAggregatedListCall) Fields(s ...googleapi.Field) *SubnetworksAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SubnetworksAggregatedListCall) IfNoneMatch(entityTag string) *SubnetworksAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksAggregatedListCall) Context(ctx context.Context) *SubnetworksAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/subnetworks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.aggregatedList" call.
// Exactly one of *SubnetworkAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *SubnetworkAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SubnetworksAggregatedListCall) Do(opts ...googleapi.CallOption) (*SubnetworkAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SubnetworkAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of subnetworks. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.subnetworks.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/subnetworks",
	//   "response": {
	//     "$ref": "SubnetworkAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SubnetworksAggregatedListCall) Pages(ctx context.Context, f func(*SubnetworkAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.subnetworks.delete":

type SubnetworksDeleteCall struct {
	s          *Service
	project    string
	region     string
	subnetwork string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified subnetwork. (== suppress_warning
// http-rest-shadowed ==)
func (r *SubnetworksService) Delete(project string, region string, subnetwork string) *SubnetworksDeleteCall {
	c := &SubnetworksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.subnetwork = subnetwork
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SubnetworksDeleteCall) RequestId(requestId string) *SubnetworksDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksDeleteCall) Fields(s ...googleapi.Field) *SubnetworksDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksDeleteCall) Context(ctx context.Context) *SubnetworksDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{subnetwork}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"subnetwork": c.subnetwork,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubnetworksDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified subnetwork. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.subnetworks.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "subnetwork"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subnetwork": {
	//       "description": "Name of the Subnetwork resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{subnetwork}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.subnetworks.expandIpCidrRange":

type SubnetworksExpandIpCidrRangeCall struct {
	s                                   *Service
	project                             string
	region                              string
	subnetwork                          string
	subnetworksexpandipcidrrangerequest *SubnetworksExpandIpCidrRangeRequest
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// ExpandIpCidrRange: Expands the IP CIDR range of the subnetwork to a
// specified value. (== suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) ExpandIpCidrRange(project string, region string, subnetwork string, subnetworksexpandipcidrrangerequest *SubnetworksExpandIpCidrRangeRequest) *SubnetworksExpandIpCidrRangeCall {
	c := &SubnetworksExpandIpCidrRangeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.subnetwork = subnetwork
	c.subnetworksexpandipcidrrangerequest = subnetworksexpandipcidrrangerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SubnetworksExpandIpCidrRangeCall) RequestId(requestId string) *SubnetworksExpandIpCidrRangeCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksExpandIpCidrRangeCall) Fields(s ...googleapi.Field) *SubnetworksExpandIpCidrRangeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksExpandIpCidrRangeCall) Context(ctx context.Context) *SubnetworksExpandIpCidrRangeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksExpandIpCidrRangeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksExpandIpCidrRangeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.subnetworksexpandipcidrrangerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{subnetwork}/expandIpCidrRange")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"subnetwork": c.subnetwork,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.expandIpCidrRange" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubnetworksExpandIpCidrRangeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Expands the IP CIDR range of the subnetwork to a specified value. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.subnetworks.expandIpCidrRange",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "subnetwork"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subnetwork": {
	//       "description": "Name of the Subnetwork resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{subnetwork}/expandIpCidrRange",
	//   "request": {
	//     "$ref": "SubnetworksExpandIpCidrRangeRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.subnetworks.get":

type SubnetworksGetCall struct {
	s            *Service
	project      string
	region       string
	subnetwork   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified subnetwork. Gets a list of available
// subnetworks list() request. (== suppress_warning http-rest-shadowed
// ==)
func (r *SubnetworksService) Get(project string, region string, subnetwork string) *SubnetworksGetCall {
	c := &SubnetworksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.subnetwork = subnetwork
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksGetCall) Fields(s ...googleapi.Field) *SubnetworksGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SubnetworksGetCall) IfNoneMatch(entityTag string) *SubnetworksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksGetCall) Context(ctx context.Context) *SubnetworksGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{subnetwork}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"subnetwork": c.subnetwork,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.get" call.
// Exactly one of *Subnetwork or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subnetwork.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubnetworksGetCall) Do(opts ...googleapi.CallOption) (*Subnetwork, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subnetwork{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified subnetwork. Gets a list of available subnetworks list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.subnetworks.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "subnetwork"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "subnetwork": {
	//       "description": "Name of the Subnetwork resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{subnetwork}",
	//   "response": {
	//     "$ref": "Subnetwork"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.subnetworks.getIamPolicy":

type SubnetworksGetIamPolicyCall struct {
	s            *Service
	project      string
	region       string
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Gets the access control policy for a resource. May be
// empty if no such policy or resource exists. (== suppress_warning
// http-rest-shadowed ==)
func (r *SubnetworksService) GetIamPolicy(project string, region string, resource string) *SubnetworksGetIamPolicyCall {
	c := &SubnetworksGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksGetIamPolicyCall) Fields(s ...googleapi.Field) *SubnetworksGetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SubnetworksGetIamPolicyCall) IfNoneMatch(entityTag string) *SubnetworksGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksGetIamPolicyCall) Context(ctx context.Context) *SubnetworksGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{resource}/getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *SubnetworksGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the access control policy for a resource. May be empty if no such policy or resource exists. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.subnetworks.getIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{resource}/getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.subnetworks.insert":

type SubnetworksInsertCall struct {
	s          *Service
	project    string
	region     string
	subnetwork *Subnetwork
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a subnetwork in the specified project using the data
// included in the request. (== suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) Insert(project string, region string, subnetwork *Subnetwork) *SubnetworksInsertCall {
	c := &SubnetworksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.subnetwork = subnetwork
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SubnetworksInsertCall) RequestId(requestId string) *SubnetworksInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksInsertCall) Fields(s ...googleapi.Field) *SubnetworksInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksInsertCall) Context(ctx context.Context) *SubnetworksInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.subnetwork)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubnetworksInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a subnetwork in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.subnetworks.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks",
	//   "request": {
	//     "$ref": "Subnetwork"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.subnetworks.list":

type SubnetworksListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of subnetworks available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) List(project string, region string) *SubnetworksListCall {
	c := &SubnetworksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SubnetworksListCall) Filter(filter string) *SubnetworksListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SubnetworksListCall) MaxResults(maxResults int64) *SubnetworksListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SubnetworksListCall) OrderBy(orderBy string) *SubnetworksListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SubnetworksListCall) PageToken(pageToken string) *SubnetworksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksListCall) Fields(s ...googleapi.Field) *SubnetworksListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SubnetworksListCall) IfNoneMatch(entityTag string) *SubnetworksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksListCall) Context(ctx context.Context) *SubnetworksListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.list" call.
// Exactly one of *SubnetworkList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SubnetworkList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SubnetworksListCall) Do(opts ...googleapi.CallOption) (*SubnetworkList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SubnetworkList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of subnetworks available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.subnetworks.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks",
	//   "response": {
	//     "$ref": "SubnetworkList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SubnetworksListCall) Pages(ctx context.Context, f func(*SubnetworkList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.subnetworks.listUsable":

type SubnetworksListUsableCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListUsable: Retrieves an aggregated list of all usable subnetworks in
// the project. The list contains all of the subnetworks in the project
// and the subnetworks that were shared by a Shared VPC host project.
// (== suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) ListUsable(project string) *SubnetworksListUsableCall {
	c := &SubnetworksListUsableCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *SubnetworksListUsableCall) Filter(filter string) *SubnetworksListUsableCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *SubnetworksListUsableCall) MaxResults(maxResults int64) *SubnetworksListUsableCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *SubnetworksListUsableCall) OrderBy(orderBy string) *SubnetworksListUsableCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *SubnetworksListUsableCall) PageToken(pageToken string) *SubnetworksListUsableCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksListUsableCall) Fields(s ...googleapi.Field) *SubnetworksListUsableCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SubnetworksListUsableCall) IfNoneMatch(entityTag string) *SubnetworksListUsableCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksListUsableCall) Context(ctx context.Context) *SubnetworksListUsableCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksListUsableCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksListUsableCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/subnetworks/listUsable")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.listUsable" call.
// Exactly one of *UsableSubnetworksAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *UsableSubnetworksAggregatedList.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SubnetworksListUsableCall) Do(opts ...googleapi.CallOption) (*UsableSubnetworksAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UsableSubnetworksAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of all usable subnetworks in the project. The list contains all of the subnetworks in the project and the subnetworks that were shared by a Shared VPC host project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.subnetworks.listUsable",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/subnetworks/listUsable",
	//   "response": {
	//     "$ref": "UsableSubnetworksAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SubnetworksListUsableCall) Pages(ctx context.Context, f func(*UsableSubnetworksAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.subnetworks.patch":

type SubnetworksPatchCall struct {
	s           *Service
	project     string
	region      string
	subnetwork  string
	subnetwork2 *Subnetwork
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Patch: Patches the specified subnetwork with the data included in the
// request. Only certain fields can up updated with a patch request as
// indicated in the field descriptions. You must specify the current
// fingeprint of the subnetwork resource being patched. (==
// suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) Patch(project string, region string, subnetwork string, subnetwork2 *Subnetwork) *SubnetworksPatchCall {
	c := &SubnetworksPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.subnetwork = subnetwork
	c.subnetwork2 = subnetwork2
	return c
}

// DrainTimeoutSeconds sets the optional parameter
// "drainTimeoutSeconds": The drain timeout specifies the upper bound in
// seconds on the amount of time allowed to drain connections from the
// current ACTIVE subnetwork to the current BACKUP subnetwork. The drain
// timeout is only applicable when the following conditions are true: -
// the subnetwork being patched has purpose =
// INTERNAL_HTTPS_LOAD_BALANCER - the subnetwork being patched has role
// = BACKUP - the patch request is setting the role to ACTIVE. Note that
// after this patch operation the roles of the ACTIVE and BACKUP
// subnetworks will be swapped.
func (c *SubnetworksPatchCall) DrainTimeoutSeconds(drainTimeoutSeconds int64) *SubnetworksPatchCall {
	c.urlParams_.Set("drainTimeoutSeconds", fmt.Sprint(drainTimeoutSeconds))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SubnetworksPatchCall) RequestId(requestId string) *SubnetworksPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksPatchCall) Fields(s ...googleapi.Field) *SubnetworksPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksPatchCall) Context(ctx context.Context) *SubnetworksPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.subnetwork2)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{subnetwork}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"subnetwork": c.subnetwork,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubnetworksPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified subnetwork with the data included in the request. Only certain fields can up updated with a patch request as indicated in the field descriptions. You must specify the current fingeprint of the subnetwork resource being patched. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.subnetworks.patch",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "subnetwork"
	//   ],
	//   "parameters": {
	//     "drainTimeoutSeconds": {
	//       "description": "The drain timeout specifies the upper bound in seconds on the amount of time allowed to drain connections from the current ACTIVE subnetwork to the current BACKUP subnetwork. The drain timeout is only applicable when the following conditions are true: - the subnetwork being patched has purpose = INTERNAL_HTTPS_LOAD_BALANCER - the subnetwork being patched has role = BACKUP - the patch request is setting the role to ACTIVE. Note that after this patch operation the roles of the ACTIVE and BACKUP subnetworks will be swapped.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subnetwork": {
	//       "description": "Name of the Subnetwork resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{subnetwork}",
	//   "request": {
	//     "$ref": "Subnetwork"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.subnetworks.setIamPolicy":

type SubnetworksSetIamPolicyCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	regionsetpolicyrequest *RegionSetPolicyRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetIamPolicy: Sets the access control policy on the specified
// resource. Replaces any existing policy. (== suppress_warning
// http-rest-shadowed ==)
func (r *SubnetworksService) SetIamPolicy(project string, region string, resource string, regionsetpolicyrequest *RegionSetPolicyRequest) *SubnetworksSetIamPolicyCall {
	c := &SubnetworksSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.regionsetpolicyrequest = regionsetpolicyrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksSetIamPolicyCall) Fields(s ...googleapi.Field) *SubnetworksSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksSetIamPolicyCall) Context(ctx context.Context) *SubnetworksSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regionsetpolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{resource}/setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *SubnetworksSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the access control policy on the specified resource. Replaces any existing policy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.subnetworks.setIamPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{resource}/setIamPolicy",
	//   "request": {
	//     "$ref": "RegionSetPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.subnetworks.setPrivateIpGoogleAccess":

type SubnetworksSetPrivateIpGoogleAccessCall struct {
	s                                          *Service
	project                                    string
	region                                     string
	subnetwork                                 string
	subnetworkssetprivateipgoogleaccessrequest *SubnetworksSetPrivateIpGoogleAccessRequest
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// SetPrivateIpGoogleAccess: Set whether VMs in this subnet can access
// Google services without assigning external IP addresses through
// Private Google Access. (== suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) SetPrivateIpGoogleAccess(project string, region string, subnetwork string, subnetworkssetprivateipgoogleaccessrequest *SubnetworksSetPrivateIpGoogleAccessRequest) *SubnetworksSetPrivateIpGoogleAccessCall {
	c := &SubnetworksSetPrivateIpGoogleAccessCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.subnetwork = subnetwork
	c.subnetworkssetprivateipgoogleaccessrequest = subnetworkssetprivateipgoogleaccessrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *SubnetworksSetPrivateIpGoogleAccessCall) RequestId(requestId string) *SubnetworksSetPrivateIpGoogleAccessCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksSetPrivateIpGoogleAccessCall) Fields(s ...googleapi.Field) *SubnetworksSetPrivateIpGoogleAccessCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksSetPrivateIpGoogleAccessCall) Context(ctx context.Context) *SubnetworksSetPrivateIpGoogleAccessCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksSetPrivateIpGoogleAccessCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksSetPrivateIpGoogleAccessCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.subnetworkssetprivateipgoogleaccessrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{subnetwork}/setPrivateIpGoogleAccess")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"subnetwork": c.subnetwork,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.setPrivateIpGoogleAccess" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubnetworksSetPrivateIpGoogleAccessCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Set whether VMs in this subnet can access Google services without assigning external IP addresses through Private Google Access. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.subnetworks.setPrivateIpGoogleAccess",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "subnetwork"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subnetwork": {
	//       "description": "Name of the Subnetwork resource.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{subnetwork}/setPrivateIpGoogleAccess",
	//   "request": {
	//     "$ref": "SubnetworksSetPrivateIpGoogleAccessRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.subnetworks.testIamPermissions":

type SubnetworksTestIamPermissionsCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *SubnetworksService) TestIamPermissions(project string, region string, resource string, testpermissionsrequest *TestPermissionsRequest) *SubnetworksTestIamPermissionsCall {
	c := &SubnetworksTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubnetworksTestIamPermissionsCall) Fields(s ...googleapi.Field) *SubnetworksTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubnetworksTestIamPermissionsCall) Context(ctx context.Context) *SubnetworksTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubnetworksTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubnetworksTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/subnetworks/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.subnetworks.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SubnetworksTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.subnetworks.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/subnetworks/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetHttpProxies.aggregatedList":

type TargetHttpProxiesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of all TargetHttpProxy resources,
// regional and global, available to the specified project. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetHttpProxiesService) AggregatedList(project string) *TargetHttpProxiesAggregatedListCall {
	c := &TargetHttpProxiesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetHttpProxiesAggregatedListCall) Filter(filter string) *TargetHttpProxiesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetHttpProxiesAggregatedListCall) MaxResults(maxResults int64) *TargetHttpProxiesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetHttpProxiesAggregatedListCall) OrderBy(orderBy string) *TargetHttpProxiesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetHttpProxiesAggregatedListCall) PageToken(pageToken string) *TargetHttpProxiesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpProxiesAggregatedListCall) Fields(s ...googleapi.Field) *TargetHttpProxiesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetHttpProxiesAggregatedListCall) IfNoneMatch(entityTag string) *TargetHttpProxiesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpProxiesAggregatedListCall) Context(ctx context.Context) *TargetHttpProxiesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpProxiesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpProxiesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/targetHttpProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpProxies.aggregatedList" call.
// Exactly one of *TargetHttpProxyAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *TargetHttpProxyAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetHttpProxiesAggregatedListCall) Do(opts ...googleapi.CallOption) (*TargetHttpProxyAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpProxyAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of all TargetHttpProxy resources, regional and global, available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetHttpProxies.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Name of the project scoping this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/targetHttpProxies",
	//   "response": {
	//     "$ref": "TargetHttpProxyAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetHttpProxiesAggregatedListCall) Pages(ctx context.Context, f func(*TargetHttpProxyAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetHttpProxies.delete":

type TargetHttpProxiesDeleteCall struct {
	s               *Service
	project         string
	targetHttpProxy string
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Delete: Deletes the specified TargetHttpProxy resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetHttpProxies/delete
func (r *TargetHttpProxiesService) Delete(project string, targetHttpProxy string) *TargetHttpProxiesDeleteCall {
	c := &TargetHttpProxiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpProxy = targetHttpProxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpProxiesDeleteCall) RequestId(requestId string) *TargetHttpProxiesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpProxiesDeleteCall) Fields(s ...googleapi.Field) *TargetHttpProxiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpProxiesDeleteCall) Context(ctx context.Context) *TargetHttpProxiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpProxiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpProxiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies/{targetHttpProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"targetHttpProxy": c.targetHttpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpProxies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpProxiesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified TargetHttpProxy resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.targetHttpProxies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpProxy": {
	//       "description": "Name of the TargetHttpProxy resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpProxies/{targetHttpProxy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpProxies.get":

type TargetHttpProxiesGetCall struct {
	s               *Service
	project         string
	targetHttpProxy string
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
	header_         http.Header
}

// Get: Returns the specified TargetHttpProxy resource. Gets a list of
// available target HTTP proxies by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetHttpProxies/get
func (r *TargetHttpProxiesService) Get(project string, targetHttpProxy string) *TargetHttpProxiesGetCall {
	c := &TargetHttpProxiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpProxy = targetHttpProxy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpProxiesGetCall) Fields(s ...googleapi.Field) *TargetHttpProxiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetHttpProxiesGetCall) IfNoneMatch(entityTag string) *TargetHttpProxiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpProxiesGetCall) Context(ctx context.Context) *TargetHttpProxiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpProxiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpProxiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies/{targetHttpProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"targetHttpProxy": c.targetHttpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpProxies.get" call.
// Exactly one of *TargetHttpProxy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetHttpProxy.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetHttpProxiesGetCall) Do(opts ...googleapi.CallOption) (*TargetHttpProxy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpProxy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified TargetHttpProxy resource. Gets a list of available target HTTP proxies by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetHttpProxies.get",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetHttpProxy": {
	//       "description": "Name of the TargetHttpProxy resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpProxies/{targetHttpProxy}",
	//   "response": {
	//     "$ref": "TargetHttpProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetHttpProxies.insert":

type TargetHttpProxiesInsertCall struct {
	s               *Service
	project         string
	targethttpproxy *TargetHttpProxy
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Creates a TargetHttpProxy resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetHttpProxies/insert
func (r *TargetHttpProxiesService) Insert(project string, targethttpproxy *TargetHttpProxy) *TargetHttpProxiesInsertCall {
	c := &TargetHttpProxiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targethttpproxy = targethttpproxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpProxiesInsertCall) RequestId(requestId string) *TargetHttpProxiesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpProxiesInsertCall) Fields(s ...googleapi.Field) *TargetHttpProxiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpProxiesInsertCall) Context(ctx context.Context) *TargetHttpProxiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpProxiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpProxiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targethttpproxy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpProxies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpProxiesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a TargetHttpProxy resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetHttpProxies.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpProxies",
	//   "request": {
	//     "$ref": "TargetHttpProxy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpProxies.list":

type TargetHttpProxiesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of TargetHttpProxy resources available to
// the specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetHttpProxies/list
func (r *TargetHttpProxiesService) List(project string) *TargetHttpProxiesListCall {
	c := &TargetHttpProxiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetHttpProxiesListCall) Filter(filter string) *TargetHttpProxiesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetHttpProxiesListCall) MaxResults(maxResults int64) *TargetHttpProxiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetHttpProxiesListCall) OrderBy(orderBy string) *TargetHttpProxiesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetHttpProxiesListCall) PageToken(pageToken string) *TargetHttpProxiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpProxiesListCall) Fields(s ...googleapi.Field) *TargetHttpProxiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetHttpProxiesListCall) IfNoneMatch(entityTag string) *TargetHttpProxiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpProxiesListCall) Context(ctx context.Context) *TargetHttpProxiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpProxiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpProxiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpProxies.list" call.
// Exactly one of *TargetHttpProxyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetHttpProxyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetHttpProxiesListCall) Do(opts ...googleapi.CallOption) (*TargetHttpProxyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpProxyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of TargetHttpProxy resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetHttpProxies.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpProxies",
	//   "response": {
	//     "$ref": "TargetHttpProxyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetHttpProxiesListCall) Pages(ctx context.Context, f func(*TargetHttpProxyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetHttpProxies.setUrlMap":

type TargetHttpProxiesSetUrlMapCall struct {
	s               *Service
	project         string
	targetHttpProxy string
	urlmapreference *UrlMapReference
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// SetUrlMap: Changes the URL map for TargetHttpProxy. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetHttpProxies/setUrlMap
func (r *TargetHttpProxiesService) SetUrlMap(project string, targetHttpProxy string, urlmapreference *UrlMapReference) *TargetHttpProxiesSetUrlMapCall {
	c := &TargetHttpProxiesSetUrlMapCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpProxy = targetHttpProxy
	c.urlmapreference = urlmapreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpProxiesSetUrlMapCall) RequestId(requestId string) *TargetHttpProxiesSetUrlMapCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpProxiesSetUrlMapCall) Fields(s ...googleapi.Field) *TargetHttpProxiesSetUrlMapCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpProxiesSetUrlMapCall) Context(ctx context.Context) *TargetHttpProxiesSetUrlMapCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpProxiesSetUrlMapCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpProxiesSetUrlMapCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmapreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/targetHttpProxies/{targetHttpProxy}/setUrlMap")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":         c.project,
		"targetHttpProxy": c.targetHttpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpProxies.setUrlMap" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpProxiesSetUrlMapCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the URL map for TargetHttpProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetHttpProxies.setUrlMap",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpProxy": {
	//       "description": "Name of the TargetHttpProxy to set a URL map for.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/targetHttpProxies/{targetHttpProxy}/setUrlMap",
	//   "request": {
	//     "$ref": "UrlMapReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpsProxies.aggregatedList":

type TargetHttpsProxiesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of all TargetHttpsProxy resources,
// regional and global, available to the specified project. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) AggregatedList(project string) *TargetHttpsProxiesAggregatedListCall {
	c := &TargetHttpsProxiesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetHttpsProxiesAggregatedListCall) Filter(filter string) *TargetHttpsProxiesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetHttpsProxiesAggregatedListCall) MaxResults(maxResults int64) *TargetHttpsProxiesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetHttpsProxiesAggregatedListCall) OrderBy(orderBy string) *TargetHttpsProxiesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetHttpsProxiesAggregatedListCall) PageToken(pageToken string) *TargetHttpsProxiesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesAggregatedListCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetHttpsProxiesAggregatedListCall) IfNoneMatch(entityTag string) *TargetHttpsProxiesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesAggregatedListCall) Context(ctx context.Context) *TargetHttpsProxiesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/targetHttpsProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.aggregatedList" call.
// Exactly one of *TargetHttpsProxyAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *TargetHttpsProxyAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetHttpsProxiesAggregatedListCall) Do(opts ...googleapi.CallOption) (*TargetHttpsProxyAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpsProxyAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of all TargetHttpsProxy resources, regional and global, available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetHttpsProxies.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Name of the project scoping this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/targetHttpsProxies",
	//   "response": {
	//     "$ref": "TargetHttpsProxyAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetHttpsProxiesAggregatedListCall) Pages(ctx context.Context, f func(*TargetHttpsProxyAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetHttpsProxies.delete":

type TargetHttpsProxiesDeleteCall struct {
	s                *Service
	project          string
	targetHttpsProxy string
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Delete: Deletes the specified TargetHttpsProxy resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) Delete(project string, targetHttpsProxy string) *TargetHttpsProxiesDeleteCall {
	c := &TargetHttpsProxiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpsProxy = targetHttpsProxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpsProxiesDeleteCall) RequestId(requestId string) *TargetHttpsProxiesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesDeleteCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesDeleteCall) Context(ctx context.Context) *TargetHttpsProxiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpsProxies/{targetHttpsProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpsProxiesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified TargetHttpsProxy resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.targetHttpsProxies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpsProxies/{targetHttpsProxy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpsProxies.get":

type TargetHttpsProxiesGetCall struct {
	s                *Service
	project          string
	targetHttpsProxy string
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// Get: Returns the specified TargetHttpsProxy resource. Gets a list of
// available target HTTPS proxies by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) Get(project string, targetHttpsProxy string) *TargetHttpsProxiesGetCall {
	c := &TargetHttpsProxiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpsProxy = targetHttpsProxy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesGetCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetHttpsProxiesGetCall) IfNoneMatch(entityTag string) *TargetHttpsProxiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesGetCall) Context(ctx context.Context) *TargetHttpsProxiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpsProxies/{targetHttpsProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.get" call.
// Exactly one of *TargetHttpsProxy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetHttpsProxy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetHttpsProxiesGetCall) Do(opts ...googleapi.CallOption) (*TargetHttpsProxy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpsProxy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified TargetHttpsProxy resource. Gets a list of available target HTTPS proxies by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetHttpsProxies.get",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpsProxies/{targetHttpsProxy}",
	//   "response": {
	//     "$ref": "TargetHttpsProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetHttpsProxies.insert":

type TargetHttpsProxiesInsertCall struct {
	s                *Service
	project          string
	targethttpsproxy *TargetHttpsProxy
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Insert: Creates a TargetHttpsProxy resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) Insert(project string, targethttpsproxy *TargetHttpsProxy) *TargetHttpsProxiesInsertCall {
	c := &TargetHttpsProxiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targethttpsproxy = targethttpsproxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpsProxiesInsertCall) RequestId(requestId string) *TargetHttpsProxiesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesInsertCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesInsertCall) Context(ctx context.Context) *TargetHttpsProxiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targethttpsproxy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpsProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpsProxiesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a TargetHttpsProxy resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetHttpsProxies.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpsProxies",
	//   "request": {
	//     "$ref": "TargetHttpsProxy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpsProxies.list":

type TargetHttpsProxiesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of TargetHttpsProxy resources available to
// the specified project. (== suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) List(project string) *TargetHttpsProxiesListCall {
	c := &TargetHttpsProxiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetHttpsProxiesListCall) Filter(filter string) *TargetHttpsProxiesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetHttpsProxiesListCall) MaxResults(maxResults int64) *TargetHttpsProxiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetHttpsProxiesListCall) OrderBy(orderBy string) *TargetHttpsProxiesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetHttpsProxiesListCall) PageToken(pageToken string) *TargetHttpsProxiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesListCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetHttpsProxiesListCall) IfNoneMatch(entityTag string) *TargetHttpsProxiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesListCall) Context(ctx context.Context) *TargetHttpsProxiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpsProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.list" call.
// Exactly one of *TargetHttpsProxyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetHttpsProxyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetHttpsProxiesListCall) Do(opts ...googleapi.CallOption) (*TargetHttpsProxyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetHttpsProxyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of TargetHttpsProxy resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetHttpsProxies.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpsProxies",
	//   "response": {
	//     "$ref": "TargetHttpsProxyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetHttpsProxiesListCall) Pages(ctx context.Context, f func(*TargetHttpsProxyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetHttpsProxies.setQuicOverride":

type TargetHttpsProxiesSetQuicOverrideCall struct {
	s                                        *Service
	project                                  string
	targetHttpsProxy                         string
	targethttpsproxiessetquicoverriderequest *TargetHttpsProxiesSetQuicOverrideRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// SetQuicOverride: Sets the QUIC override policy for TargetHttpsProxy.
// (== suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) SetQuicOverride(project string, targetHttpsProxy string, targethttpsproxiessetquicoverriderequest *TargetHttpsProxiesSetQuicOverrideRequest) *TargetHttpsProxiesSetQuicOverrideCall {
	c := &TargetHttpsProxiesSetQuicOverrideCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpsProxy = targetHttpsProxy
	c.targethttpsproxiessetquicoverriderequest = targethttpsproxiessetquicoverriderequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpsProxiesSetQuicOverrideCall) RequestId(requestId string) *TargetHttpsProxiesSetQuicOverrideCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesSetQuicOverrideCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesSetQuicOverrideCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesSetQuicOverrideCall) Context(ctx context.Context) *TargetHttpsProxiesSetQuicOverrideCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesSetQuicOverrideCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesSetQuicOverrideCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targethttpsproxiessetquicoverriderequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpsProxies/{targetHttpsProxy}/setQuicOverride")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.setQuicOverride" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpsProxiesSetQuicOverrideCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the QUIC override policy for TargetHttpsProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetHttpsProxies.setQuicOverride",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource to set the QUIC override policy for. The name should conform to RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpsProxies/{targetHttpsProxy}/setQuicOverride",
	//   "request": {
	//     "$ref": "TargetHttpsProxiesSetQuicOverrideRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpsProxies.setSslCertificates":

type TargetHttpsProxiesSetSslCertificatesCall struct {
	s                                           *Service
	project                                     string
	targetHttpsProxy                            string
	targethttpsproxiessetsslcertificatesrequest *TargetHttpsProxiesSetSslCertificatesRequest
	urlParams_                                  gensupport.URLParams
	ctx_                                        context.Context
	header_                                     http.Header
}

// SetSslCertificates: Replaces SslCertificates for TargetHttpsProxy.
// (== suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) SetSslCertificates(project string, targetHttpsProxy string, targethttpsproxiessetsslcertificatesrequest *TargetHttpsProxiesSetSslCertificatesRequest) *TargetHttpsProxiesSetSslCertificatesCall {
	c := &TargetHttpsProxiesSetSslCertificatesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpsProxy = targetHttpsProxy
	c.targethttpsproxiessetsslcertificatesrequest = targethttpsproxiessetsslcertificatesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpsProxiesSetSslCertificatesCall) RequestId(requestId string) *TargetHttpsProxiesSetSslCertificatesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesSetSslCertificatesCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesSetSslCertificatesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesSetSslCertificatesCall) Context(ctx context.Context) *TargetHttpsProxiesSetSslCertificatesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesSetSslCertificatesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesSetSslCertificatesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targethttpsproxiessetsslcertificatesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/targetHttpsProxies/{targetHttpsProxy}/setSslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.setSslCertificates" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpsProxiesSetSslCertificatesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Replaces SslCertificates for TargetHttpsProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetHttpsProxies.setSslCertificates",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource to set an SslCertificates resource for.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/targetHttpsProxies/{targetHttpsProxy}/setSslCertificates",
	//   "request": {
	//     "$ref": "TargetHttpsProxiesSetSslCertificatesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpsProxies.setSslPolicy":

type TargetHttpsProxiesSetSslPolicyCall struct {
	s                  *Service
	project            string
	targetHttpsProxy   string
	sslpolicyreference *SslPolicyReference
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// SetSslPolicy: Sets the SSL policy for TargetHttpsProxy. The SSL
// policy specifies the server-side support for SSL features. This
// affects connections between clients and the HTTPS proxy load
// balancer. They do not affect the connection between the load balancer
// and the backends. (== suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) SetSslPolicy(project string, targetHttpsProxy string, sslpolicyreference *SslPolicyReference) *TargetHttpsProxiesSetSslPolicyCall {
	c := &TargetHttpsProxiesSetSslPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpsProxy = targetHttpsProxy
	c.sslpolicyreference = sslpolicyreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpsProxiesSetSslPolicyCall) RequestId(requestId string) *TargetHttpsProxiesSetSslPolicyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesSetSslPolicyCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesSetSslPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesSetSslPolicyCall) Context(ctx context.Context) *TargetHttpsProxiesSetSslPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesSetSslPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesSetSslPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.sslpolicyreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpsProxies/{targetHttpsProxy}/setSslPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.setSslPolicy" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpsProxiesSetSslPolicyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the SSL policy for TargetHttpsProxy. The SSL policy specifies the server-side support for SSL features. This affects connections between clients and the HTTPS proxy load balancer. They do not affect the connection between the load balancer and the backends. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetHttpsProxies.setSslPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource whose SSL policy is to be set. The name must be 1-63 characters long, and comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetHttpsProxies/{targetHttpsProxy}/setSslPolicy",
	//   "request": {
	//     "$ref": "SslPolicyReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetHttpsProxies.setUrlMap":

type TargetHttpsProxiesSetUrlMapCall struct {
	s                *Service
	project          string
	targetHttpsProxy string
	urlmapreference  *UrlMapReference
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// SetUrlMap: Changes the URL map for TargetHttpsProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetHttpsProxiesService) SetUrlMap(project string, targetHttpsProxy string, urlmapreference *UrlMapReference) *TargetHttpsProxiesSetUrlMapCall {
	c := &TargetHttpsProxiesSetUrlMapCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetHttpsProxy = targetHttpsProxy
	c.urlmapreference = urlmapreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetHttpsProxiesSetUrlMapCall) RequestId(requestId string) *TargetHttpsProxiesSetUrlMapCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetHttpsProxiesSetUrlMapCall) Fields(s ...googleapi.Field) *TargetHttpsProxiesSetUrlMapCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetHttpsProxiesSetUrlMapCall) Context(ctx context.Context) *TargetHttpsProxiesSetUrlMapCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetHttpsProxiesSetUrlMapCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetHttpsProxiesSetUrlMapCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmapreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/targetHttpsProxies/{targetHttpsProxy}/setUrlMap")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"targetHttpsProxy": c.targetHttpsProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetHttpsProxies.setUrlMap" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetHttpsProxiesSetUrlMapCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the URL map for TargetHttpsProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetHttpsProxies.setUrlMap",
	//   "parameterOrder": [
	//     "project",
	//     "targetHttpsProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetHttpsProxy": {
	//       "description": "Name of the TargetHttpsProxy resource whose URL map is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/targetHttpsProxies/{targetHttpsProxy}/setUrlMap",
	//   "request": {
	//     "$ref": "UrlMapReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetInstances.aggregatedList":

type TargetInstancesAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of target instances. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetInstances/aggregatedList
func (r *TargetInstancesService) AggregatedList(project string) *TargetInstancesAggregatedListCall {
	c := &TargetInstancesAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetInstancesAggregatedListCall) Filter(filter string) *TargetInstancesAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetInstancesAggregatedListCall) MaxResults(maxResults int64) *TargetInstancesAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetInstancesAggregatedListCall) OrderBy(orderBy string) *TargetInstancesAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetInstancesAggregatedListCall) PageToken(pageToken string) *TargetInstancesAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetInstancesAggregatedListCall) Fields(s ...googleapi.Field) *TargetInstancesAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetInstancesAggregatedListCall) IfNoneMatch(entityTag string) *TargetInstancesAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetInstancesAggregatedListCall) Context(ctx context.Context) *TargetInstancesAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetInstancesAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetInstancesAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/targetInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetInstances.aggregatedList" call.
// Exactly one of *TargetInstanceAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *TargetInstanceAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetInstancesAggregatedListCall) Do(opts ...googleapi.CallOption) (*TargetInstanceAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetInstanceAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of target instances. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetInstances.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/targetInstances",
	//   "response": {
	//     "$ref": "TargetInstanceAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetInstancesAggregatedListCall) Pages(ctx context.Context, f func(*TargetInstanceAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetInstances.delete":

type TargetInstancesDeleteCall struct {
	s              *Service
	project        string
	zone           string
	targetInstance string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified TargetInstance resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetInstances/delete
func (r *TargetInstancesService) Delete(project string, zone string, targetInstance string) *TargetInstancesDeleteCall {
	c := &TargetInstancesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.targetInstance = targetInstance
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetInstancesDeleteCall) RequestId(requestId string) *TargetInstancesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetInstancesDeleteCall) Fields(s ...googleapi.Field) *TargetInstancesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetInstancesDeleteCall) Context(ctx context.Context) *TargetInstancesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetInstancesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetInstancesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances/{targetInstance}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"zone":           c.zone,
		"targetInstance": c.targetInstance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetInstances.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetInstancesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified TargetInstance resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.targetInstances.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "targetInstance"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetInstance": {
	//       "description": "Name of the TargetInstance resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/targetInstances/{targetInstance}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetInstances.get":

type TargetInstancesGetCall struct {
	s              *Service
	project        string
	zone           string
	targetInstance string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified TargetInstance resource. Gets a list of
// available target instances by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetInstances/get
func (r *TargetInstancesService) Get(project string, zone string, targetInstance string) *TargetInstancesGetCall {
	c := &TargetInstancesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.targetInstance = targetInstance
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetInstancesGetCall) Fields(s ...googleapi.Field) *TargetInstancesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetInstancesGetCall) IfNoneMatch(entityTag string) *TargetInstancesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetInstancesGetCall) Context(ctx context.Context) *TargetInstancesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetInstancesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetInstancesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances/{targetInstance}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"zone":           c.zone,
		"targetInstance": c.targetInstance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetInstances.get" call.
// Exactly one of *TargetInstance or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetInstance.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetInstancesGetCall) Do(opts ...googleapi.CallOption) (*TargetInstance, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetInstance{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified TargetInstance resource. Gets a list of available target instances by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetInstances.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "targetInstance"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetInstance": {
	//       "description": "Name of the TargetInstance resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/targetInstances/{targetInstance}",
	//   "response": {
	//     "$ref": "TargetInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetInstances.insert":

type TargetInstancesInsertCall struct {
	s              *Service
	project        string
	zone           string
	targetinstance *TargetInstance
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a TargetInstance resource in the specified project
// and zone using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetInstances/insert
func (r *TargetInstancesService) Insert(project string, zone string, targetinstance *TargetInstance) *TargetInstancesInsertCall {
	c := &TargetInstancesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.targetinstance = targetinstance
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetInstancesInsertCall) RequestId(requestId string) *TargetInstancesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetInstancesInsertCall) Fields(s ...googleapi.Field) *TargetInstancesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetInstancesInsertCall) Context(ctx context.Context) *TargetInstancesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetInstancesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetInstancesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetinstance)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetInstances.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetInstancesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a TargetInstance resource in the specified project and zone using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetInstances.insert",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/targetInstances",
	//   "request": {
	//     "$ref": "TargetInstance"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetInstances.list":

type TargetInstancesListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of TargetInstance resources available to the
// specified project and zone. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetInstances/list
func (r *TargetInstancesService) List(project string, zone string) *TargetInstancesListCall {
	c := &TargetInstancesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetInstancesListCall) Filter(filter string) *TargetInstancesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetInstancesListCall) MaxResults(maxResults int64) *TargetInstancesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetInstancesListCall) OrderBy(orderBy string) *TargetInstancesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetInstancesListCall) PageToken(pageToken string) *TargetInstancesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetInstancesListCall) Fields(s ...googleapi.Field) *TargetInstancesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetInstancesListCall) IfNoneMatch(entityTag string) *TargetInstancesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetInstancesListCall) Context(ctx context.Context) *TargetInstancesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetInstancesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetInstancesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetInstances.list" call.
// Exactly one of *TargetInstanceList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetInstanceList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetInstancesListCall) Do(opts ...googleapi.CallOption) (*TargetInstanceList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetInstanceList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of TargetInstance resources available to the specified project and zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetInstances.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/targetInstances",
	//   "response": {
	//     "$ref": "TargetInstanceList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetInstancesListCall) Pages(ctx context.Context, f func(*TargetInstanceList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetPools.addHealthCheck":

type TargetPoolsAddHealthCheckCall struct {
	s                                *Service
	project                          string
	region                           string
	targetPool                       string
	targetpoolsaddhealthcheckrequest *TargetPoolsAddHealthCheckRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// AddHealthCheck: Adds health check URLs to a target pool. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/addHealthCheck
func (r *TargetPoolsService) AddHealthCheck(project string, region string, targetPool string, targetpoolsaddhealthcheckrequest *TargetPoolsAddHealthCheckRequest) *TargetPoolsAddHealthCheckCall {
	c := &TargetPoolsAddHealthCheckCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	c.targetpoolsaddhealthcheckrequest = targetpoolsaddhealthcheckrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetPoolsAddHealthCheckCall) RequestId(requestId string) *TargetPoolsAddHealthCheckCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsAddHealthCheckCall) Fields(s ...googleapi.Field) *TargetPoolsAddHealthCheckCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsAddHealthCheckCall) Context(ctx context.Context) *TargetPoolsAddHealthCheckCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsAddHealthCheckCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsAddHealthCheckCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsaddhealthcheckrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/addHealthCheck")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.addHealthCheck" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsAddHealthCheckCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds health check URLs to a target pool. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetPools.addHealthCheck",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the target pool to add a health check to.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}/addHealthCheck",
	//   "request": {
	//     "$ref": "TargetPoolsAddHealthCheckRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetPools.addInstance":

type TargetPoolsAddInstanceCall struct {
	s                             *Service
	project                       string
	region                        string
	targetPool                    string
	targetpoolsaddinstancerequest *TargetPoolsAddInstanceRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// AddInstance: Adds an instance to a target pool. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/addInstance
func (r *TargetPoolsService) AddInstance(project string, region string, targetPool string, targetpoolsaddinstancerequest *TargetPoolsAddInstanceRequest) *TargetPoolsAddInstanceCall {
	c := &TargetPoolsAddInstanceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	c.targetpoolsaddinstancerequest = targetpoolsaddinstancerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetPoolsAddInstanceCall) RequestId(requestId string) *TargetPoolsAddInstanceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsAddInstanceCall) Fields(s ...googleapi.Field) *TargetPoolsAddInstanceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsAddInstanceCall) Context(ctx context.Context) *TargetPoolsAddInstanceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsAddInstanceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsAddInstanceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsaddinstancerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/addInstance")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.addInstance" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsAddInstanceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Adds an instance to a target pool. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetPools.addInstance",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the TargetPool resource to add instances to.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}/addInstance",
	//   "request": {
	//     "$ref": "TargetPoolsAddInstanceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetPools.aggregatedList":

type TargetPoolsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of target pools. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/aggregatedList
func (r *TargetPoolsService) AggregatedList(project string) *TargetPoolsAggregatedListCall {
	c := &TargetPoolsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetPoolsAggregatedListCall) Filter(filter string) *TargetPoolsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetPoolsAggregatedListCall) MaxResults(maxResults int64) *TargetPoolsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetPoolsAggregatedListCall) OrderBy(orderBy string) *TargetPoolsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetPoolsAggregatedListCall) PageToken(pageToken string) *TargetPoolsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsAggregatedListCall) Fields(s ...googleapi.Field) *TargetPoolsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetPoolsAggregatedListCall) IfNoneMatch(entityTag string) *TargetPoolsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsAggregatedListCall) Context(ctx context.Context) *TargetPoolsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/targetPools")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.aggregatedList" call.
// Exactly one of *TargetPoolAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *TargetPoolAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetPoolsAggregatedListCall) Do(opts ...googleapi.CallOption) (*TargetPoolAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetPoolAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of target pools. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetPools.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/targetPools",
	//   "response": {
	//     "$ref": "TargetPoolAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetPoolsAggregatedListCall) Pages(ctx context.Context, f func(*TargetPoolAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetPools.delete":

type TargetPoolsDeleteCall struct {
	s          *Service
	project    string
	region     string
	targetPool string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified target pool. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/delete
func (r *TargetPoolsService) Delete(project string, region string, targetPool string) *TargetPoolsDeleteCall {
	c := &TargetPoolsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetPoolsDeleteCall) RequestId(requestId string) *TargetPoolsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsDeleteCall) Fields(s ...googleapi.Field) *TargetPoolsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsDeleteCall) Context(ctx context.Context) *TargetPoolsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified target pool. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.targetPools.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the TargetPool resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetPools.get":

type TargetPoolsGetCall struct {
	s            *Service
	project      string
	region       string
	targetPool   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified target pool. Gets a list of available
// target pools by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/get
func (r *TargetPoolsService) Get(project string, region string, targetPool string) *TargetPoolsGetCall {
	c := &TargetPoolsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsGetCall) Fields(s ...googleapi.Field) *TargetPoolsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetPoolsGetCall) IfNoneMatch(entityTag string) *TargetPoolsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsGetCall) Context(ctx context.Context) *TargetPoolsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.get" call.
// Exactly one of *TargetPool or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetPool.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsGetCall) Do(opts ...googleapi.CallOption) (*TargetPool, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetPool{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified target pool. Gets a list of available target pools by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetPools.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the TargetPool resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}",
	//   "response": {
	//     "$ref": "TargetPool"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetPools.getHealth":

type TargetPoolsGetHealthCall struct {
	s                 *Service
	project           string
	region            string
	targetPool        string
	instancereference *InstanceReference
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// GetHealth: Gets the most recent health check results for each IP for
// the instance that is referenced by the given target pool. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/getHealth
func (r *TargetPoolsService) GetHealth(project string, region string, targetPool string, instancereference *InstanceReference) *TargetPoolsGetHealthCall {
	c := &TargetPoolsGetHealthCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	c.instancereference = instancereference
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsGetHealthCall) Fields(s ...googleapi.Field) *TargetPoolsGetHealthCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsGetHealthCall) Context(ctx context.Context) *TargetPoolsGetHealthCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsGetHealthCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsGetHealthCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancereference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/getHealth")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.getHealth" call.
// Exactly one of *TargetPoolInstanceHealth or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *TargetPoolInstanceHealth.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetPoolsGetHealthCall) Do(opts ...googleapi.CallOption) (*TargetPoolInstanceHealth, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetPoolInstanceHealth{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the most recent health check results for each IP for the instance that is referenced by the given target pool. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetPools.getHealth",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the TargetPool resource to which the queried instance belongs.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}/getHealth",
	//   "request": {
	//     "$ref": "InstanceReference"
	//   },
	//   "response": {
	//     "$ref": "TargetPoolInstanceHealth"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetPools.insert":

type TargetPoolsInsertCall struct {
	s          *Service
	project    string
	region     string
	targetpool *TargetPool
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a target pool in the specified project and region
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/insert
func (r *TargetPoolsService) Insert(project string, region string, targetpool *TargetPool) *TargetPoolsInsertCall {
	c := &TargetPoolsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetpool = targetpool
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetPoolsInsertCall) RequestId(requestId string) *TargetPoolsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsInsertCall) Fields(s ...googleapi.Field) *TargetPoolsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsInsertCall) Context(ctx context.Context) *TargetPoolsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpool)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a target pool in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetPools.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools",
	//   "request": {
	//     "$ref": "TargetPool"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetPools.list":

type TargetPoolsListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of target pools available to the specified
// project and region. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/list
func (r *TargetPoolsService) List(project string, region string) *TargetPoolsListCall {
	c := &TargetPoolsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetPoolsListCall) Filter(filter string) *TargetPoolsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetPoolsListCall) MaxResults(maxResults int64) *TargetPoolsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetPoolsListCall) OrderBy(orderBy string) *TargetPoolsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetPoolsListCall) PageToken(pageToken string) *TargetPoolsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsListCall) Fields(s ...googleapi.Field) *TargetPoolsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetPoolsListCall) IfNoneMatch(entityTag string) *TargetPoolsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsListCall) Context(ctx context.Context) *TargetPoolsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.list" call.
// Exactly one of *TargetPoolList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetPoolList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetPoolsListCall) Do(opts ...googleapi.CallOption) (*TargetPoolList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetPoolList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of target pools available to the specified project and region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetPools.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools",
	//   "response": {
	//     "$ref": "TargetPoolList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetPoolsListCall) Pages(ctx context.Context, f func(*TargetPoolList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetPools.removeHealthCheck":

type TargetPoolsRemoveHealthCheckCall struct {
	s                                   *Service
	project                             string
	region                              string
	targetPool                          string
	targetpoolsremovehealthcheckrequest *TargetPoolsRemoveHealthCheckRequest
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// RemoveHealthCheck: Removes health check URL from a target pool. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/removeHealthCheck
func (r *TargetPoolsService) RemoveHealthCheck(project string, region string, targetPool string, targetpoolsremovehealthcheckrequest *TargetPoolsRemoveHealthCheckRequest) *TargetPoolsRemoveHealthCheckCall {
	c := &TargetPoolsRemoveHealthCheckCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	c.targetpoolsremovehealthcheckrequest = targetpoolsremovehealthcheckrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetPoolsRemoveHealthCheckCall) RequestId(requestId string) *TargetPoolsRemoveHealthCheckCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsRemoveHealthCheckCall) Fields(s ...googleapi.Field) *TargetPoolsRemoveHealthCheckCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsRemoveHealthCheckCall) Context(ctx context.Context) *TargetPoolsRemoveHealthCheckCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsRemoveHealthCheckCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsRemoveHealthCheckCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsremovehealthcheckrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/removeHealthCheck")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.removeHealthCheck" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsRemoveHealthCheckCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Removes health check URL from a target pool. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetPools.removeHealthCheck",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the target pool to remove health checks from.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}/removeHealthCheck",
	//   "request": {
	//     "$ref": "TargetPoolsRemoveHealthCheckRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetPools.removeInstance":

type TargetPoolsRemoveInstanceCall struct {
	s                                *Service
	project                          string
	region                           string
	targetPool                       string
	targetpoolsremoveinstancerequest *TargetPoolsRemoveInstanceRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// RemoveInstance: Removes instance URL from a target pool. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/removeInstance
func (r *TargetPoolsService) RemoveInstance(project string, region string, targetPool string, targetpoolsremoveinstancerequest *TargetPoolsRemoveInstanceRequest) *TargetPoolsRemoveInstanceCall {
	c := &TargetPoolsRemoveInstanceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	c.targetpoolsremoveinstancerequest = targetpoolsremoveinstancerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetPoolsRemoveInstanceCall) RequestId(requestId string) *TargetPoolsRemoveInstanceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsRemoveInstanceCall) Fields(s ...googleapi.Field) *TargetPoolsRemoveInstanceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsRemoveInstanceCall) Context(ctx context.Context) *TargetPoolsRemoveInstanceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsRemoveInstanceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsRemoveInstanceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsremoveinstancerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/removeInstance")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.removeInstance" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsRemoveInstanceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Removes instance URL from a target pool. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetPools.removeInstance",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the TargetPool resource to remove instances from.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}/removeInstance",
	//   "request": {
	//     "$ref": "TargetPoolsRemoveInstanceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetPools.setBackup":

type TargetPoolsSetBackupCall struct {
	s               *Service
	project         string
	region          string
	targetPool      string
	targetreference *TargetReference
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// SetBackup: Changes a backup target pool's configurations. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/targetPools/setBackup
func (r *TargetPoolsService) SetBackup(project string, region string, targetPool string, targetreference *TargetReference) *TargetPoolsSetBackupCall {
	c := &TargetPoolsSetBackupCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetPool = targetPool
	c.targetreference = targetreference
	return c
}

// FailoverRatio sets the optional parameter "failoverRatio": New
// failoverRatio value for the target pool.
func (c *TargetPoolsSetBackupCall) FailoverRatio(failoverRatio float64) *TargetPoolsSetBackupCall {
	c.urlParams_.Set("failoverRatio", fmt.Sprint(failoverRatio))
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetPoolsSetBackupCall) RequestId(requestId string) *TargetPoolsSetBackupCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetPoolsSetBackupCall) Fields(s ...googleapi.Field) *TargetPoolsSetBackupCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetPoolsSetBackupCall) Context(ctx context.Context) *TargetPoolsSetBackupCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetPoolsSetBackupCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetPoolsSetBackupCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/setBackup")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"targetPool": c.targetPool,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetPools.setBackup" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetPoolsSetBackupCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes a backup target pool's configurations. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetPools.setBackup",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetPool"
	//   ],
	//   "parameters": {
	//     "failoverRatio": {
	//       "description": "New failoverRatio value for the target pool.",
	//       "format": "float",
	//       "location": "query",
	//       "type": "number"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetPool": {
	//       "description": "Name of the TargetPool resource to set a backup pool for.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetPools/{targetPool}/setBackup",
	//   "request": {
	//     "$ref": "TargetReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetSslProxies.delete":

type TargetSslProxiesDeleteCall struct {
	s              *Service
	project        string
	targetSslProxy string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified TargetSslProxy resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetSslProxiesService) Delete(project string, targetSslProxy string) *TargetSslProxiesDeleteCall {
	c := &TargetSslProxiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetSslProxy = targetSslProxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetSslProxiesDeleteCall) RequestId(requestId string) *TargetSslProxiesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesDeleteCall) Fields(s ...googleapi.Field) *TargetSslProxiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesDeleteCall) Context(ctx context.Context) *TargetSslProxiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies/{targetSslProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetSslProxy": c.targetSslProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetSslProxiesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified TargetSslProxy resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.targetSslProxies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "targetSslProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetSslProxy": {
	//       "description": "Name of the TargetSslProxy resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies/{targetSslProxy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetSslProxies.get":

type TargetSslProxiesGetCall struct {
	s              *Service
	project        string
	targetSslProxy string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified TargetSslProxy resource. Gets a list of
// available target SSL proxies by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetSslProxiesService) Get(project string, targetSslProxy string) *TargetSslProxiesGetCall {
	c := &TargetSslProxiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetSslProxy = targetSslProxy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesGetCall) Fields(s ...googleapi.Field) *TargetSslProxiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetSslProxiesGetCall) IfNoneMatch(entityTag string) *TargetSslProxiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesGetCall) Context(ctx context.Context) *TargetSslProxiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies/{targetSslProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetSslProxy": c.targetSslProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.get" call.
// Exactly one of *TargetSslProxy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetSslProxy.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetSslProxiesGetCall) Do(opts ...googleapi.CallOption) (*TargetSslProxy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetSslProxy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified TargetSslProxy resource. Gets a list of available target SSL proxies by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetSslProxies.get",
	//   "parameterOrder": [
	//     "project",
	//     "targetSslProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetSslProxy": {
	//       "description": "Name of the TargetSslProxy resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies/{targetSslProxy}",
	//   "response": {
	//     "$ref": "TargetSslProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetSslProxies.insert":

type TargetSslProxiesInsertCall struct {
	s              *Service
	project        string
	targetsslproxy *TargetSslProxy
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a TargetSslProxy resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *TargetSslProxiesService) Insert(project string, targetsslproxy *TargetSslProxy) *TargetSslProxiesInsertCall {
	c := &TargetSslProxiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetsslproxy = targetsslproxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetSslProxiesInsertCall) RequestId(requestId string) *TargetSslProxiesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesInsertCall) Fields(s ...googleapi.Field) *TargetSslProxiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesInsertCall) Context(ctx context.Context) *TargetSslProxiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetsslproxy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetSslProxiesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a TargetSslProxy resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetSslProxies.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies",
	//   "request": {
	//     "$ref": "TargetSslProxy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetSslProxies.list":

type TargetSslProxiesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of TargetSslProxy resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *TargetSslProxiesService) List(project string) *TargetSslProxiesListCall {
	c := &TargetSslProxiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetSslProxiesListCall) Filter(filter string) *TargetSslProxiesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetSslProxiesListCall) MaxResults(maxResults int64) *TargetSslProxiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetSslProxiesListCall) OrderBy(orderBy string) *TargetSslProxiesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetSslProxiesListCall) PageToken(pageToken string) *TargetSslProxiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesListCall) Fields(s ...googleapi.Field) *TargetSslProxiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetSslProxiesListCall) IfNoneMatch(entityTag string) *TargetSslProxiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesListCall) Context(ctx context.Context) *TargetSslProxiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.list" call.
// Exactly one of *TargetSslProxyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetSslProxyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetSslProxiesListCall) Do(opts ...googleapi.CallOption) (*TargetSslProxyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetSslProxyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of TargetSslProxy resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetSslProxies.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies",
	//   "response": {
	//     "$ref": "TargetSslProxyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetSslProxiesListCall) Pages(ctx context.Context, f func(*TargetSslProxyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetSslProxies.setBackendService":

type TargetSslProxiesSetBackendServiceCall struct {
	s                                        *Service
	project                                  string
	targetSslProxy                           string
	targetsslproxiessetbackendservicerequest *TargetSslProxiesSetBackendServiceRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// SetBackendService: Changes the BackendService for TargetSslProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetSslProxiesService) SetBackendService(project string, targetSslProxy string, targetsslproxiessetbackendservicerequest *TargetSslProxiesSetBackendServiceRequest) *TargetSslProxiesSetBackendServiceCall {
	c := &TargetSslProxiesSetBackendServiceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetSslProxy = targetSslProxy
	c.targetsslproxiessetbackendservicerequest = targetsslproxiessetbackendservicerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetSslProxiesSetBackendServiceCall) RequestId(requestId string) *TargetSslProxiesSetBackendServiceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesSetBackendServiceCall) Fields(s ...googleapi.Field) *TargetSslProxiesSetBackendServiceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesSetBackendServiceCall) Context(ctx context.Context) *TargetSslProxiesSetBackendServiceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesSetBackendServiceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesSetBackendServiceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetsslproxiessetbackendservicerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies/{targetSslProxy}/setBackendService")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetSslProxy": c.targetSslProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.setBackendService" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetSslProxiesSetBackendServiceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the BackendService for TargetSslProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetSslProxies.setBackendService",
	//   "parameterOrder": [
	//     "project",
	//     "targetSslProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetSslProxy": {
	//       "description": "Name of the TargetSslProxy resource whose BackendService resource is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies/{targetSslProxy}/setBackendService",
	//   "request": {
	//     "$ref": "TargetSslProxiesSetBackendServiceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetSslProxies.setProxyHeader":

type TargetSslProxiesSetProxyHeaderCall struct {
	s                                     *Service
	project                               string
	targetSslProxy                        string
	targetsslproxiessetproxyheaderrequest *TargetSslProxiesSetProxyHeaderRequest
	urlParams_                            gensupport.URLParams
	ctx_                                  context.Context
	header_                               http.Header
}

// SetProxyHeader: Changes the ProxyHeaderType for TargetSslProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetSslProxiesService) SetProxyHeader(project string, targetSslProxy string, targetsslproxiessetproxyheaderrequest *TargetSslProxiesSetProxyHeaderRequest) *TargetSslProxiesSetProxyHeaderCall {
	c := &TargetSslProxiesSetProxyHeaderCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetSslProxy = targetSslProxy
	c.targetsslproxiessetproxyheaderrequest = targetsslproxiessetproxyheaderrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetSslProxiesSetProxyHeaderCall) RequestId(requestId string) *TargetSslProxiesSetProxyHeaderCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesSetProxyHeaderCall) Fields(s ...googleapi.Field) *TargetSslProxiesSetProxyHeaderCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesSetProxyHeaderCall) Context(ctx context.Context) *TargetSslProxiesSetProxyHeaderCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesSetProxyHeaderCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesSetProxyHeaderCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetsslproxiessetproxyheaderrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies/{targetSslProxy}/setProxyHeader")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetSslProxy": c.targetSslProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.setProxyHeader" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetSslProxiesSetProxyHeaderCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the ProxyHeaderType for TargetSslProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetSslProxies.setProxyHeader",
	//   "parameterOrder": [
	//     "project",
	//     "targetSslProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetSslProxy": {
	//       "description": "Name of the TargetSslProxy resource whose ProxyHeader is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies/{targetSslProxy}/setProxyHeader",
	//   "request": {
	//     "$ref": "TargetSslProxiesSetProxyHeaderRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetSslProxies.setSslCertificates":

type TargetSslProxiesSetSslCertificatesCall struct {
	s                                         *Service
	project                                   string
	targetSslProxy                            string
	targetsslproxiessetsslcertificatesrequest *TargetSslProxiesSetSslCertificatesRequest
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// SetSslCertificates: Changes SslCertificates for TargetSslProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetSslProxiesService) SetSslCertificates(project string, targetSslProxy string, targetsslproxiessetsslcertificatesrequest *TargetSslProxiesSetSslCertificatesRequest) *TargetSslProxiesSetSslCertificatesCall {
	c := &TargetSslProxiesSetSslCertificatesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetSslProxy = targetSslProxy
	c.targetsslproxiessetsslcertificatesrequest = targetsslproxiessetsslcertificatesrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetSslProxiesSetSslCertificatesCall) RequestId(requestId string) *TargetSslProxiesSetSslCertificatesCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesSetSslCertificatesCall) Fields(s ...googleapi.Field) *TargetSslProxiesSetSslCertificatesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesSetSslCertificatesCall) Context(ctx context.Context) *TargetSslProxiesSetSslCertificatesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesSetSslCertificatesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesSetSslCertificatesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetsslproxiessetsslcertificatesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies/{targetSslProxy}/setSslCertificates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetSslProxy": c.targetSslProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.setSslCertificates" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetSslProxiesSetSslCertificatesCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes SslCertificates for TargetSslProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetSslProxies.setSslCertificates",
	//   "parameterOrder": [
	//     "project",
	//     "targetSslProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetSslProxy": {
	//       "description": "Name of the TargetSslProxy resource whose SslCertificate resource is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies/{targetSslProxy}/setSslCertificates",
	//   "request": {
	//     "$ref": "TargetSslProxiesSetSslCertificatesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetSslProxies.setSslPolicy":

type TargetSslProxiesSetSslPolicyCall struct {
	s                  *Service
	project            string
	targetSslProxy     string
	sslpolicyreference *SslPolicyReference
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// SetSslPolicy: Sets the SSL policy for TargetSslProxy. The SSL policy
// specifies the server-side support for SSL features. This affects
// connections between clients and the SSL proxy load balancer. They do
// not affect the connection between the load balancer and the backends.
// (== suppress_warning http-rest-shadowed ==)
func (r *TargetSslProxiesService) SetSslPolicy(project string, targetSslProxy string, sslpolicyreference *SslPolicyReference) *TargetSslProxiesSetSslPolicyCall {
	c := &TargetSslProxiesSetSslPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetSslProxy = targetSslProxy
	c.sslpolicyreference = sslpolicyreference
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetSslProxiesSetSslPolicyCall) RequestId(requestId string) *TargetSslProxiesSetSslPolicyCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetSslProxiesSetSslPolicyCall) Fields(s ...googleapi.Field) *TargetSslProxiesSetSslPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetSslProxiesSetSslPolicyCall) Context(ctx context.Context) *TargetSslProxiesSetSslPolicyCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetSslProxiesSetSslPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetSslProxiesSetSslPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.sslpolicyreference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetSslProxies/{targetSslProxy}/setSslPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetSslProxy": c.targetSslProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetSslProxies.setSslPolicy" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetSslProxiesSetSslPolicyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the SSL policy for TargetSslProxy. The SSL policy specifies the server-side support for SSL features. This affects connections between clients and the SSL proxy load balancer. They do not affect the connection between the load balancer and the backends. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetSslProxies.setSslPolicy",
	//   "parameterOrder": [
	//     "project",
	//     "targetSslProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetSslProxy": {
	//       "description": "Name of the TargetSslProxy resource whose SSL policy is to be set. The name must be 1-63 characters long, and comply with RFC1035.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetSslProxies/{targetSslProxy}/setSslPolicy",
	//   "request": {
	//     "$ref": "SslPolicyReference"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetTcpProxies.delete":

type TargetTcpProxiesDeleteCall struct {
	s              *Service
	project        string
	targetTcpProxy string
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Delete: Deletes the specified TargetTcpProxy resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetTcpProxiesService) Delete(project string, targetTcpProxy string) *TargetTcpProxiesDeleteCall {
	c := &TargetTcpProxiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetTcpProxy = targetTcpProxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetTcpProxiesDeleteCall) RequestId(requestId string) *TargetTcpProxiesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetTcpProxiesDeleteCall) Fields(s ...googleapi.Field) *TargetTcpProxiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetTcpProxiesDeleteCall) Context(ctx context.Context) *TargetTcpProxiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetTcpProxiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetTcpProxiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetTcpProxies/{targetTcpProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetTcpProxy": c.targetTcpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetTcpProxies.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetTcpProxiesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified TargetTcpProxy resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.targetTcpProxies.delete",
	//   "parameterOrder": [
	//     "project",
	//     "targetTcpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetTcpProxy": {
	//       "description": "Name of the TargetTcpProxy resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetTcpProxies/{targetTcpProxy}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetTcpProxies.get":

type TargetTcpProxiesGetCall struct {
	s              *Service
	project        string
	targetTcpProxy string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Returns the specified TargetTcpProxy resource. Gets a list of
// available target TCP proxies by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetTcpProxiesService) Get(project string, targetTcpProxy string) *TargetTcpProxiesGetCall {
	c := &TargetTcpProxiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetTcpProxy = targetTcpProxy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetTcpProxiesGetCall) Fields(s ...googleapi.Field) *TargetTcpProxiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetTcpProxiesGetCall) IfNoneMatch(entityTag string) *TargetTcpProxiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetTcpProxiesGetCall) Context(ctx context.Context) *TargetTcpProxiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetTcpProxiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetTcpProxiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetTcpProxies/{targetTcpProxy}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetTcpProxy": c.targetTcpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetTcpProxies.get" call.
// Exactly one of *TargetTcpProxy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetTcpProxy.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetTcpProxiesGetCall) Do(opts ...googleapi.CallOption) (*TargetTcpProxy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetTcpProxy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified TargetTcpProxy resource. Gets a list of available target TCP proxies by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetTcpProxies.get",
	//   "parameterOrder": [
	//     "project",
	//     "targetTcpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetTcpProxy": {
	//       "description": "Name of the TargetTcpProxy resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetTcpProxies/{targetTcpProxy}",
	//   "response": {
	//     "$ref": "TargetTcpProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetTcpProxies.insert":

type TargetTcpProxiesInsertCall struct {
	s              *Service
	project        string
	targettcpproxy *TargetTcpProxy
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Creates a TargetTcpProxy resource in the specified project
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *TargetTcpProxiesService) Insert(project string, targettcpproxy *TargetTcpProxy) *TargetTcpProxiesInsertCall {
	c := &TargetTcpProxiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targettcpproxy = targettcpproxy
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetTcpProxiesInsertCall) RequestId(requestId string) *TargetTcpProxiesInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetTcpProxiesInsertCall) Fields(s ...googleapi.Field) *TargetTcpProxiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetTcpProxiesInsertCall) Context(ctx context.Context) *TargetTcpProxiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetTcpProxiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetTcpProxiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targettcpproxy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetTcpProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetTcpProxies.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetTcpProxiesInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a TargetTcpProxy resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetTcpProxies.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetTcpProxies",
	//   "request": {
	//     "$ref": "TargetTcpProxy"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetTcpProxies.list":

type TargetTcpProxiesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of TargetTcpProxy resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
func (r *TargetTcpProxiesService) List(project string) *TargetTcpProxiesListCall {
	c := &TargetTcpProxiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetTcpProxiesListCall) Filter(filter string) *TargetTcpProxiesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetTcpProxiesListCall) MaxResults(maxResults int64) *TargetTcpProxiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetTcpProxiesListCall) OrderBy(orderBy string) *TargetTcpProxiesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetTcpProxiesListCall) PageToken(pageToken string) *TargetTcpProxiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetTcpProxiesListCall) Fields(s ...googleapi.Field) *TargetTcpProxiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetTcpProxiesListCall) IfNoneMatch(entityTag string) *TargetTcpProxiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetTcpProxiesListCall) Context(ctx context.Context) *TargetTcpProxiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetTcpProxiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetTcpProxiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetTcpProxies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetTcpProxies.list" call.
// Exactly one of *TargetTcpProxyList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetTcpProxyList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetTcpProxiesListCall) Do(opts ...googleapi.CallOption) (*TargetTcpProxyList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetTcpProxyList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of TargetTcpProxy resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetTcpProxies.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetTcpProxies",
	//   "response": {
	//     "$ref": "TargetTcpProxyList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetTcpProxiesListCall) Pages(ctx context.Context, f func(*TargetTcpProxyList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetTcpProxies.setBackendService":

type TargetTcpProxiesSetBackendServiceCall struct {
	s                                        *Service
	project                                  string
	targetTcpProxy                           string
	targettcpproxiessetbackendservicerequest *TargetTcpProxiesSetBackendServiceRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// SetBackendService: Changes the BackendService for TargetTcpProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetTcpProxiesService) SetBackendService(project string, targetTcpProxy string, targettcpproxiessetbackendservicerequest *TargetTcpProxiesSetBackendServiceRequest) *TargetTcpProxiesSetBackendServiceCall {
	c := &TargetTcpProxiesSetBackendServiceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetTcpProxy = targetTcpProxy
	c.targettcpproxiessetbackendservicerequest = targettcpproxiessetbackendservicerequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetTcpProxiesSetBackendServiceCall) RequestId(requestId string) *TargetTcpProxiesSetBackendServiceCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetTcpProxiesSetBackendServiceCall) Fields(s ...googleapi.Field) *TargetTcpProxiesSetBackendServiceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetTcpProxiesSetBackendServiceCall) Context(ctx context.Context) *TargetTcpProxiesSetBackendServiceCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetTcpProxiesSetBackendServiceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetTcpProxiesSetBackendServiceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targettcpproxiessetbackendservicerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetTcpProxies/{targetTcpProxy}/setBackendService")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetTcpProxy": c.targetTcpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetTcpProxies.setBackendService" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetTcpProxiesSetBackendServiceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the BackendService for TargetTcpProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetTcpProxies.setBackendService",
	//   "parameterOrder": [
	//     "project",
	//     "targetTcpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetTcpProxy": {
	//       "description": "Name of the TargetTcpProxy resource whose BackendService resource is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetTcpProxies/{targetTcpProxy}/setBackendService",
	//   "request": {
	//     "$ref": "TargetTcpProxiesSetBackendServiceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetTcpProxies.setProxyHeader":

type TargetTcpProxiesSetProxyHeaderCall struct {
	s                                     *Service
	project                               string
	targetTcpProxy                        string
	targettcpproxiessetproxyheaderrequest *TargetTcpProxiesSetProxyHeaderRequest
	urlParams_                            gensupport.URLParams
	ctx_                                  context.Context
	header_                               http.Header
}

// SetProxyHeader: Changes the ProxyHeaderType for TargetTcpProxy. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetTcpProxiesService) SetProxyHeader(project string, targetTcpProxy string, targettcpproxiessetproxyheaderrequest *TargetTcpProxiesSetProxyHeaderRequest) *TargetTcpProxiesSetProxyHeaderCall {
	c := &TargetTcpProxiesSetProxyHeaderCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.targetTcpProxy = targetTcpProxy
	c.targettcpproxiessetproxyheaderrequest = targettcpproxiessetproxyheaderrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetTcpProxiesSetProxyHeaderCall) RequestId(requestId string) *TargetTcpProxiesSetProxyHeaderCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetTcpProxiesSetProxyHeaderCall) Fields(s ...googleapi.Field) *TargetTcpProxiesSetProxyHeaderCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetTcpProxiesSetProxyHeaderCall) Context(ctx context.Context) *TargetTcpProxiesSetProxyHeaderCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetTcpProxiesSetProxyHeaderCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetTcpProxiesSetProxyHeaderCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targettcpproxiessetproxyheaderrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetTcpProxies/{targetTcpProxy}/setProxyHeader")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":        c.project,
		"targetTcpProxy": c.targetTcpProxy,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetTcpProxies.setProxyHeader" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetTcpProxiesSetProxyHeaderCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Changes the ProxyHeaderType for TargetTcpProxy. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetTcpProxies.setProxyHeader",
	//   "parameterOrder": [
	//     "project",
	//     "targetTcpProxy"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetTcpProxy": {
	//       "description": "Name of the TargetTcpProxy resource whose ProxyHeader is to be set.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/targetTcpProxies/{targetTcpProxy}/setProxyHeader",
	//   "request": {
	//     "$ref": "TargetTcpProxiesSetProxyHeaderRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetVpnGateways.aggregatedList":

type TargetVpnGatewaysAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of target VPN gateways.
// (== suppress_warning http-rest-shadowed ==)
func (r *TargetVpnGatewaysService) AggregatedList(project string) *TargetVpnGatewaysAggregatedListCall {
	c := &TargetVpnGatewaysAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetVpnGatewaysAggregatedListCall) Filter(filter string) *TargetVpnGatewaysAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetVpnGatewaysAggregatedListCall) MaxResults(maxResults int64) *TargetVpnGatewaysAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetVpnGatewaysAggregatedListCall) OrderBy(orderBy string) *TargetVpnGatewaysAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetVpnGatewaysAggregatedListCall) PageToken(pageToken string) *TargetVpnGatewaysAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetVpnGatewaysAggregatedListCall) Fields(s ...googleapi.Field) *TargetVpnGatewaysAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetVpnGatewaysAggregatedListCall) IfNoneMatch(entityTag string) *TargetVpnGatewaysAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetVpnGatewaysAggregatedListCall) Context(ctx context.Context) *TargetVpnGatewaysAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetVpnGatewaysAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetVpnGatewaysAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/targetVpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetVpnGateways.aggregatedList" call.
// Exactly one of *TargetVpnGatewayAggregatedList or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *TargetVpnGatewayAggregatedList.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetVpnGatewaysAggregatedListCall) Do(opts ...googleapi.CallOption) (*TargetVpnGatewayAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetVpnGatewayAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of target VPN gateways. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetVpnGateways.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/targetVpnGateways",
	//   "response": {
	//     "$ref": "TargetVpnGatewayAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetVpnGatewaysAggregatedListCall) Pages(ctx context.Context, f func(*TargetVpnGatewayAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.targetVpnGateways.delete":

type TargetVpnGatewaysDeleteCall struct {
	s                *Service
	project          string
	region           string
	targetVpnGateway string
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Delete: Deletes the specified target VPN gateway. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetVpnGatewaysService) Delete(project string, region string, targetVpnGateway string) *TargetVpnGatewaysDeleteCall {
	c := &TargetVpnGatewaysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetVpnGateway = targetVpnGateway
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetVpnGatewaysDeleteCall) RequestId(requestId string) *TargetVpnGatewaysDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetVpnGatewaysDeleteCall) Fields(s ...googleapi.Field) *TargetVpnGatewaysDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetVpnGatewaysDeleteCall) Context(ctx context.Context) *TargetVpnGatewaysDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetVpnGatewaysDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetVpnGatewaysDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetVpnGateways/{targetVpnGateway}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"region":           c.region,
		"targetVpnGateway": c.targetVpnGateway,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetVpnGateways.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetVpnGatewaysDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified target VPN gateway. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.targetVpnGateways.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetVpnGateway"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetVpnGateway": {
	//       "description": "Name of the target VPN gateway to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetVpnGateways/{targetVpnGateway}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetVpnGateways.get":

type TargetVpnGatewaysGetCall struct {
	s                *Service
	project          string
	region           string
	targetVpnGateway string
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// Get: Returns the specified target VPN gateway. Gets a list of
// available target VPN gateways by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *TargetVpnGatewaysService) Get(project string, region string, targetVpnGateway string) *TargetVpnGatewaysGetCall {
	c := &TargetVpnGatewaysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetVpnGateway = targetVpnGateway
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetVpnGatewaysGetCall) Fields(s ...googleapi.Field) *TargetVpnGatewaysGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetVpnGatewaysGetCall) IfNoneMatch(entityTag string) *TargetVpnGatewaysGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetVpnGatewaysGetCall) Context(ctx context.Context) *TargetVpnGatewaysGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetVpnGatewaysGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetVpnGatewaysGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetVpnGateways/{targetVpnGateway}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":          c.project,
		"region":           c.region,
		"targetVpnGateway": c.targetVpnGateway,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetVpnGateways.get" call.
// Exactly one of *TargetVpnGateway or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetVpnGateway.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetVpnGatewaysGetCall) Do(opts ...googleapi.CallOption) (*TargetVpnGateway, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetVpnGateway{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified target VPN gateway. Gets a list of available target VPN gateways by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetVpnGateways.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "targetVpnGateway"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetVpnGateway": {
	//       "description": "Name of the target VPN gateway to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetVpnGateways/{targetVpnGateway}",
	//   "response": {
	//     "$ref": "TargetVpnGateway"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.targetVpnGateways.insert":

type TargetVpnGatewaysInsertCall struct {
	s                *Service
	project          string
	region           string
	targetvpngateway *TargetVpnGateway
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Insert: Creates a target VPN gateway in the specified project and
// region using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *TargetVpnGatewaysService) Insert(project string, region string, targetvpngateway *TargetVpnGateway) *TargetVpnGatewaysInsertCall {
	c := &TargetVpnGatewaysInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.targetvpngateway = targetvpngateway
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *TargetVpnGatewaysInsertCall) RequestId(requestId string) *TargetVpnGatewaysInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetVpnGatewaysInsertCall) Fields(s ...googleapi.Field) *TargetVpnGatewaysInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetVpnGatewaysInsertCall) Context(ctx context.Context) *TargetVpnGatewaysInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetVpnGatewaysInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetVpnGatewaysInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetvpngateway)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetVpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetVpnGateways.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TargetVpnGatewaysInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a target VPN gateway in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.targetVpnGateways.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetVpnGateways",
	//   "request": {
	//     "$ref": "TargetVpnGateway"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.targetVpnGateways.list":

type TargetVpnGatewaysListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of target VPN gateways available to the
// specified project and region. (== suppress_warning http-rest-shadowed
// ==)
func (r *TargetVpnGatewaysService) List(project string, region string) *TargetVpnGatewaysListCall {
	c := &TargetVpnGatewaysListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *TargetVpnGatewaysListCall) Filter(filter string) *TargetVpnGatewaysListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *TargetVpnGatewaysListCall) MaxResults(maxResults int64) *TargetVpnGatewaysListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *TargetVpnGatewaysListCall) OrderBy(orderBy string) *TargetVpnGatewaysListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *TargetVpnGatewaysListCall) PageToken(pageToken string) *TargetVpnGatewaysListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetVpnGatewaysListCall) Fields(s ...googleapi.Field) *TargetVpnGatewaysListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TargetVpnGatewaysListCall) IfNoneMatch(entityTag string) *TargetVpnGatewaysListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TargetVpnGatewaysListCall) Context(ctx context.Context) *TargetVpnGatewaysListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetVpnGatewaysListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetVpnGatewaysListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetVpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.targetVpnGateways.list" call.
// Exactly one of *TargetVpnGatewayList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetVpnGatewayList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetVpnGatewaysListCall) Do(opts ...googleapi.CallOption) (*TargetVpnGatewayList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetVpnGatewayList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of target VPN gateways available to the specified project and region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.targetVpnGateways.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/targetVpnGateways",
	//   "response": {
	//     "$ref": "TargetVpnGatewayList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TargetVpnGatewaysListCall) Pages(ctx context.Context, f func(*TargetVpnGatewayList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.urlMaps.aggregatedList":

type UrlMapsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves the list of all UrlMap resources, regional
// and global, available to the specified project. (== suppress_warning
// http-rest-shadowed ==)
func (r *UrlMapsService) AggregatedList(project string) *UrlMapsAggregatedListCall {
	c := &UrlMapsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *UrlMapsAggregatedListCall) Filter(filter string) *UrlMapsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *UrlMapsAggregatedListCall) MaxResults(maxResults int64) *UrlMapsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *UrlMapsAggregatedListCall) OrderBy(orderBy string) *UrlMapsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *UrlMapsAggregatedListCall) PageToken(pageToken string) *UrlMapsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsAggregatedListCall) Fields(s ...googleapi.Field) *UrlMapsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UrlMapsAggregatedListCall) IfNoneMatch(entityTag string) *UrlMapsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsAggregatedListCall) Context(ctx context.Context) *UrlMapsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/urlMaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.aggregatedList" call.
// Exactly one of *UrlMapsAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UrlMapsAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UrlMapsAggregatedListCall) Do(opts ...googleapi.CallOption) (*UrlMapsAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UrlMapsAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of all UrlMap resources, regional and global, available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.urlMaps.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Name of the project scoping this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/urlMaps",
	//   "response": {
	//     "$ref": "UrlMapsAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *UrlMapsAggregatedListCall) Pages(ctx context.Context, f func(*UrlMapsAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.urlMaps.delete":

type UrlMapsDeleteCall struct {
	s          *Service
	project    string
	urlMap     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified UrlMap resource. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/urlMaps/delete
func (r *UrlMapsService) Delete(project string, urlMap string) *UrlMapsDeleteCall {
	c := &UrlMapsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.urlMap = urlMap
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *UrlMapsDeleteCall) RequestId(requestId string) *UrlMapsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsDeleteCall) Fields(s ...googleapi.Field) *UrlMapsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsDeleteCall) Context(ctx context.Context) *UrlMapsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UrlMapsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified UrlMap resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.urlMaps.delete",
	//   "parameterOrder": [
	//     "project",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps/{urlMap}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.urlMaps.get":

type UrlMapsGetCall struct {
	s            *Service
	project      string
	urlMap       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified UrlMap resource. Gets a list of available
// URL maps by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/urlMaps/get
func (r *UrlMapsService) Get(project string, urlMap string) *UrlMapsGetCall {
	c := &UrlMapsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.urlMap = urlMap
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsGetCall) Fields(s ...googleapi.Field) *UrlMapsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UrlMapsGetCall) IfNoneMatch(entityTag string) *UrlMapsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsGetCall) Context(ctx context.Context) *UrlMapsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.get" call.
// Exactly one of *UrlMap or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UrlMap.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *UrlMapsGetCall) Do(opts ...googleapi.CallOption) (*UrlMap, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UrlMap{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified UrlMap resource. Gets a list of available URL maps by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.urlMaps.get",
	//   "parameterOrder": [
	//     "project",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps/{urlMap}",
	//   "response": {
	//     "$ref": "UrlMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.urlMaps.insert":

type UrlMapsInsertCall struct {
	s          *Service
	project    string
	urlmap     *UrlMap
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a UrlMap resource in the specified project using the
// data included in the request. (== suppress_warning http-rest-shadowed
// ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/urlMaps/insert
func (r *UrlMapsService) Insert(project string, urlmap *UrlMap) *UrlMapsInsertCall {
	c := &UrlMapsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.urlmap = urlmap
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *UrlMapsInsertCall) RequestId(requestId string) *UrlMapsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsInsertCall) Fields(s ...googleapi.Field) *UrlMapsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsInsertCall) Context(ctx context.Context) *UrlMapsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UrlMapsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a UrlMap resource in the specified project using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.urlMaps.insert",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps",
	//   "request": {
	//     "$ref": "UrlMap"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.urlMaps.invalidateCache":

type UrlMapsInvalidateCacheCall struct {
	s                     *Service
	project               string
	urlMap                string
	cacheinvalidationrule *CacheInvalidationRule
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// InvalidateCache: Initiates a cache invalidation operation,
// invalidating the specified path, scoped to the specified UrlMap. (==
// suppress_warning http-rest-shadowed ==)
func (r *UrlMapsService) InvalidateCache(project string, urlMap string, cacheinvalidationrule *CacheInvalidationRule) *UrlMapsInvalidateCacheCall {
	c := &UrlMapsInvalidateCacheCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.urlMap = urlMap
	c.cacheinvalidationrule = cacheinvalidationrule
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *UrlMapsInvalidateCacheCall) RequestId(requestId string) *UrlMapsInvalidateCacheCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsInvalidateCacheCall) Fields(s ...googleapi.Field) *UrlMapsInvalidateCacheCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsInvalidateCacheCall) Context(ctx context.Context) *UrlMapsInvalidateCacheCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsInvalidateCacheCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsInvalidateCacheCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.cacheinvalidationrule)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}/invalidateCache")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.invalidateCache" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UrlMapsInvalidateCacheCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Initiates a cache invalidation operation, invalidating the specified path, scoped to the specified UrlMap. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.urlMaps.invalidateCache",
	//   "parameterOrder": [
	//     "project",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap scoping this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps/{urlMap}/invalidateCache",
	//   "request": {
	//     "$ref": "CacheInvalidationRule"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.urlMaps.list":

type UrlMapsListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of UrlMap resources available to the
// specified project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/urlMaps/list
func (r *UrlMapsService) List(project string) *UrlMapsListCall {
	c := &UrlMapsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *UrlMapsListCall) Filter(filter string) *UrlMapsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *UrlMapsListCall) MaxResults(maxResults int64) *UrlMapsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *UrlMapsListCall) OrderBy(orderBy string) *UrlMapsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *UrlMapsListCall) PageToken(pageToken string) *UrlMapsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsListCall) Fields(s ...googleapi.Field) *UrlMapsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UrlMapsListCall) IfNoneMatch(entityTag string) *UrlMapsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsListCall) Context(ctx context.Context) *UrlMapsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.list" call.
// Exactly one of *UrlMapList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UrlMapList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UrlMapsListCall) Do(opts ...googleapi.CallOption) (*UrlMapList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UrlMapList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of UrlMap resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.urlMaps.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps",
	//   "response": {
	//     "$ref": "UrlMapList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *UrlMapsListCall) Pages(ctx context.Context, f func(*UrlMapList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.urlMaps.patch":

type UrlMapsPatchCall struct {
	s          *Service
	project    string
	urlMap     string
	urlmap     *UrlMap
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Patches the specified UrlMap resource with the data included
// in the request. This method supports PATCH semantics and uses the
// JSON merge patch format and processing rules. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/urlMaps/patch
func (r *UrlMapsService) Patch(project string, urlMap string, urlmap *UrlMap) *UrlMapsPatchCall {
	c := &UrlMapsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.urlMap = urlMap
	c.urlmap = urlmap
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *UrlMapsPatchCall) RequestId(requestId string) *UrlMapsPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsPatchCall) Fields(s ...googleapi.Field) *UrlMapsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsPatchCall) Context(ctx context.Context) *UrlMapsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.patch" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UrlMapsPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Patches the specified UrlMap resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PATCH",
	//   "id": "compute.urlMaps.patch",
	//   "parameterOrder": [
	//     "project",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to patch.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps/{urlMap}",
	//   "request": {
	//     "$ref": "UrlMap"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.urlMaps.update":

type UrlMapsUpdateCall struct {
	s          *Service
	project    string
	urlMap     string
	urlmap     *UrlMap
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates the specified UrlMap resource with the data included
// in the request. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/urlMaps/update
func (r *UrlMapsService) Update(project string, urlMap string, urlmap *UrlMap) *UrlMapsUpdateCall {
	c := &UrlMapsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.urlMap = urlMap
	c.urlmap = urlmap
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *UrlMapsUpdateCall) RequestId(requestId string) *UrlMapsUpdateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsUpdateCall) Fields(s ...googleapi.Field) *UrlMapsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsUpdateCall) Context(ctx context.Context) *UrlMapsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UrlMapsUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the specified UrlMap resource with the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "PUT",
	//   "id": "compute.urlMaps.update",
	//   "parameterOrder": [
	//     "project",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to update.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps/{urlMap}",
	//   "request": {
	//     "$ref": "UrlMap"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.urlMaps.validate":

type UrlMapsValidateCall struct {
	s                      *Service
	project                string
	urlMap                 string
	urlmapsvalidaterequest *UrlMapsValidateRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Validate: Runs static validation for the UrlMap. In particular, the
// tests of the provided UrlMap will be run. Calling this method does
// NOT create the UrlMap. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/urlMaps/validate
func (r *UrlMapsService) Validate(project string, urlMap string, urlmapsvalidaterequest *UrlMapsValidateRequest) *UrlMapsValidateCall {
	c := &UrlMapsValidateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.urlMap = urlMap
	c.urlmapsvalidaterequest = urlmapsvalidaterequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UrlMapsValidateCall) Fields(s ...googleapi.Field) *UrlMapsValidateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UrlMapsValidateCall) Context(ctx context.Context) *UrlMapsValidateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UrlMapsValidateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UrlMapsValidateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmapsvalidaterequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}/validate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"urlMap":  c.urlMap,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.urlMaps.validate" call.
// Exactly one of *UrlMapsValidateResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UrlMapsValidateResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UrlMapsValidateCall) Do(opts ...googleapi.CallOption) (*UrlMapsValidateResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UrlMapsValidateResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Runs static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.urlMaps.validate",
	//   "parameterOrder": [
	//     "project",
	//     "urlMap"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "urlMap": {
	//       "description": "Name of the UrlMap resource to be validated as.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/global/urlMaps/{urlMap}/validate",
	//   "request": {
	//     "$ref": "UrlMapsValidateRequest"
	//   },
	//   "response": {
	//     "$ref": "UrlMapsValidateResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.vpnGateways.aggregatedList":

type VpnGatewaysAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of VPN gateways. (==
// suppress_warning http-rest-shadowed ==)
func (r *VpnGatewaysService) AggregatedList(project string) *VpnGatewaysAggregatedListCall {
	c := &VpnGatewaysAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *VpnGatewaysAggregatedListCall) Filter(filter string) *VpnGatewaysAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *VpnGatewaysAggregatedListCall) MaxResults(maxResults int64) *VpnGatewaysAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *VpnGatewaysAggregatedListCall) OrderBy(orderBy string) *VpnGatewaysAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *VpnGatewaysAggregatedListCall) PageToken(pageToken string) *VpnGatewaysAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysAggregatedListCall) Fields(s ...googleapi.Field) *VpnGatewaysAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *VpnGatewaysAggregatedListCall) IfNoneMatch(entityTag string) *VpnGatewaysAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysAggregatedListCall) Context(ctx context.Context) *VpnGatewaysAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/vpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.aggregatedList" call.
// Exactly one of *VpnGatewayAggregatedList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *VpnGatewayAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VpnGatewaysAggregatedListCall) Do(opts ...googleapi.CallOption) (*VpnGatewayAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VpnGatewayAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of VPN gateways. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.vpnGateways.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/vpnGateways",
	//   "response": {
	//     "$ref": "VpnGatewayAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *VpnGatewaysAggregatedListCall) Pages(ctx context.Context, f func(*VpnGatewayAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.vpnGateways.delete":

type VpnGatewaysDeleteCall struct {
	s          *Service
	project    string
	region     string
	vpnGateway string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified VPN gateway. (== suppress_warning
// http-rest-shadowed ==)
func (r *VpnGatewaysService) Delete(project string, region string, vpnGateway string) *VpnGatewaysDeleteCall {
	c := &VpnGatewaysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.vpnGateway = vpnGateway
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *VpnGatewaysDeleteCall) RequestId(requestId string) *VpnGatewaysDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysDeleteCall) Fields(s ...googleapi.Field) *VpnGatewaysDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysDeleteCall) Context(ctx context.Context) *VpnGatewaysDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnGateways/{vpnGateway}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"vpnGateway": c.vpnGateway,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VpnGatewaysDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified VPN gateway. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.vpnGateways.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "vpnGateway"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "vpnGateway": {
	//       "description": "Name of the VPN gateway to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnGateways/{vpnGateway}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.vpnGateways.get":

type VpnGatewaysGetCall struct {
	s            *Service
	project      string
	region       string
	vpnGateway   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified VPN gateway. Gets a list of available VPN
// gateways by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
func (r *VpnGatewaysService) Get(project string, region string, vpnGateway string) *VpnGatewaysGetCall {
	c := &VpnGatewaysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.vpnGateway = vpnGateway
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysGetCall) Fields(s ...googleapi.Field) *VpnGatewaysGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *VpnGatewaysGetCall) IfNoneMatch(entityTag string) *VpnGatewaysGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysGetCall) Context(ctx context.Context) *VpnGatewaysGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnGateways/{vpnGateway}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"vpnGateway": c.vpnGateway,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.get" call.
// Exactly one of *VpnGateway or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *VpnGateway.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VpnGatewaysGetCall) Do(opts ...googleapi.CallOption) (*VpnGateway, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VpnGateway{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified VPN gateway. Gets a list of available VPN gateways by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.vpnGateways.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "vpnGateway"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "vpnGateway": {
	//       "description": "Name of the VPN gateway to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnGateways/{vpnGateway}",
	//   "response": {
	//     "$ref": "VpnGateway"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.vpnGateways.getStatus":

type VpnGatewaysGetStatusCall struct {
	s            *Service
	project      string
	region       string
	vpnGateway   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetStatus: Returns the status for the specified VPN gateway. (==
// suppress_warning http-rest-shadowed ==)
func (r *VpnGatewaysService) GetStatus(project string, region string, vpnGateway string) *VpnGatewaysGetStatusCall {
	c := &VpnGatewaysGetStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.vpnGateway = vpnGateway
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysGetStatusCall) Fields(s ...googleapi.Field) *VpnGatewaysGetStatusCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *VpnGatewaysGetStatusCall) IfNoneMatch(entityTag string) *VpnGatewaysGetStatusCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysGetStatusCall) Context(ctx context.Context) *VpnGatewaysGetStatusCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysGetStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysGetStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnGateways/{vpnGateway}/getStatus")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":    c.project,
		"region":     c.region,
		"vpnGateway": c.vpnGateway,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.getStatus" call.
// Exactly one of *VpnGatewaysGetStatusResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *VpnGatewaysGetStatusResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VpnGatewaysGetStatusCall) Do(opts ...googleapi.CallOption) (*VpnGatewaysGetStatusResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VpnGatewaysGetStatusResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the status for the specified VPN gateway. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.vpnGateways.getStatus",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "vpnGateway"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "vpnGateway": {
	//       "description": "Name of the VPN gateway to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnGateways/{vpnGateway}/getStatus",
	//   "response": {
	//     "$ref": "VpnGatewaysGetStatusResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.vpnGateways.insert":

type VpnGatewaysInsertCall struct {
	s          *Service
	project    string
	region     string
	vpngateway *VpnGateway
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a VPN gateway in the specified project and region
// using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *VpnGatewaysService) Insert(project string, region string, vpngateway *VpnGateway) *VpnGatewaysInsertCall {
	c := &VpnGatewaysInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.vpngateway = vpngateway
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *VpnGatewaysInsertCall) RequestId(requestId string) *VpnGatewaysInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysInsertCall) Fields(s ...googleapi.Field) *VpnGatewaysInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysInsertCall) Context(ctx context.Context) *VpnGatewaysInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.vpngateway)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VpnGatewaysInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a VPN gateway in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.vpnGateways.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnGateways",
	//   "request": {
	//     "$ref": "VpnGateway"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.vpnGateways.list":

type VpnGatewaysListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of VPN gateways available to the specified
// project and region. (== suppress_warning http-rest-shadowed ==)
func (r *VpnGatewaysService) List(project string, region string) *VpnGatewaysListCall {
	c := &VpnGatewaysListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *VpnGatewaysListCall) Filter(filter string) *VpnGatewaysListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *VpnGatewaysListCall) MaxResults(maxResults int64) *VpnGatewaysListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *VpnGatewaysListCall) OrderBy(orderBy string) *VpnGatewaysListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *VpnGatewaysListCall) PageToken(pageToken string) *VpnGatewaysListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysListCall) Fields(s ...googleapi.Field) *VpnGatewaysListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *VpnGatewaysListCall) IfNoneMatch(entityTag string) *VpnGatewaysListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysListCall) Context(ctx context.Context) *VpnGatewaysListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnGateways")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.list" call.
// Exactly one of *VpnGatewayList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *VpnGatewayList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VpnGatewaysListCall) Do(opts ...googleapi.CallOption) (*VpnGatewayList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VpnGatewayList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of VPN gateways available to the specified project and region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.vpnGateways.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnGateways",
	//   "response": {
	//     "$ref": "VpnGatewayList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *VpnGatewaysListCall) Pages(ctx context.Context, f func(*VpnGatewayList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.vpnGateways.setLabels":

type VpnGatewaysSetLabelsCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	regionsetlabelsrequest *RegionSetLabelsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// SetLabels: Sets the labels on a VpnGateway. To learn more about
// labels, read the Labeling Resources documentation. (==
// suppress_warning http-rest-shadowed ==)
func (r *VpnGatewaysService) SetLabels(project string, region string, resource string, regionsetlabelsrequest *RegionSetLabelsRequest) *VpnGatewaysSetLabelsCall {
	c := &VpnGatewaysSetLabelsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.regionsetlabelsrequest = regionsetlabelsrequest
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *VpnGatewaysSetLabelsCall) RequestId(requestId string) *VpnGatewaysSetLabelsCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysSetLabelsCall) Fields(s ...googleapi.Field) *VpnGatewaysSetLabelsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysSetLabelsCall) Context(ctx context.Context) *VpnGatewaysSetLabelsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysSetLabelsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysSetLabelsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.regionsetlabelsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnGateways/{resource}/setLabels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.setLabels" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VpnGatewaysSetLabelsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets the labels on a VpnGateway. To learn more about labels, read the Labeling Resources documentation. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.vpnGateways.setLabels",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnGateways/{resource}/setLabels",
	//   "request": {
	//     "$ref": "RegionSetLabelsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.vpnGateways.testIamPermissions":

type VpnGatewaysTestIamPermissionsCall struct {
	s                      *Service
	project                string
	region                 string
	resource               string
	testpermissionsrequest *TestPermissionsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified resource. (== suppress_warning http-rest-shadowed ==)
func (r *VpnGatewaysService) TestIamPermissions(project string, region string, resource string, testpermissionsrequest *TestPermissionsRequest) *VpnGatewaysTestIamPermissionsCall {
	c := &VpnGatewaysTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.resource = resource
	c.testpermissionsrequest = testpermissionsrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnGatewaysTestIamPermissionsCall) Fields(s ...googleapi.Field) *VpnGatewaysTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnGatewaysTestIamPermissionsCall) Context(ctx context.Context) *VpnGatewaysTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnGatewaysTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnGatewaysTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testpermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnGateways/{resource}/testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":  c.project,
		"region":   c.region,
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnGateways.testIamPermissions" call.
// Exactly one of *TestPermissionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VpnGatewaysTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.vpnGateways.testIamPermissions",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "resource"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "The name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Name or id of the resource for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnGateways/{resource}/testIamPermissions",
	//   "request": {
	//     "$ref": "TestPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.vpnTunnels.aggregatedList":

type VpnTunnelsAggregatedListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// AggregatedList: Retrieves an aggregated list of VPN tunnels. (==
// suppress_warning http-rest-shadowed ==)
func (r *VpnTunnelsService) AggregatedList(project string) *VpnTunnelsAggregatedListCall {
	c := &VpnTunnelsAggregatedListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *VpnTunnelsAggregatedListCall) Filter(filter string) *VpnTunnelsAggregatedListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *VpnTunnelsAggregatedListCall) MaxResults(maxResults int64) *VpnTunnelsAggregatedListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *VpnTunnelsAggregatedListCall) OrderBy(orderBy string) *VpnTunnelsAggregatedListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *VpnTunnelsAggregatedListCall) PageToken(pageToken string) *VpnTunnelsAggregatedListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnTunnelsAggregatedListCall) Fields(s ...googleapi.Field) *VpnTunnelsAggregatedListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *VpnTunnelsAggregatedListCall) IfNoneMatch(entityTag string) *VpnTunnelsAggregatedListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnTunnelsAggregatedListCall) Context(ctx context.Context) *VpnTunnelsAggregatedListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnTunnelsAggregatedListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnTunnelsAggregatedListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/vpnTunnels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnTunnels.aggregatedList" call.
// Exactly one of *VpnTunnelAggregatedList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *VpnTunnelAggregatedList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VpnTunnelsAggregatedListCall) Do(opts ...googleapi.CallOption) (*VpnTunnelAggregatedList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VpnTunnelAggregatedList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves an aggregated list of VPN tunnels. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.vpnTunnels.aggregatedList",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/aggregated/vpnTunnels",
	//   "response": {
	//     "$ref": "VpnTunnelAggregatedList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *VpnTunnelsAggregatedListCall) Pages(ctx context.Context, f func(*VpnTunnelAggregatedList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.vpnTunnels.delete":

type VpnTunnelsDeleteCall struct {
	s          *Service
	project    string
	region     string
	vpnTunnel  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified VpnTunnel resource. (==
// suppress_warning http-rest-shadowed ==)
func (r *VpnTunnelsService) Delete(project string, region string, vpnTunnel string) *VpnTunnelsDeleteCall {
	c := &VpnTunnelsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.vpnTunnel = vpnTunnel
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *VpnTunnelsDeleteCall) RequestId(requestId string) *VpnTunnelsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnTunnelsDeleteCall) Fields(s ...googleapi.Field) *VpnTunnelsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnTunnelsDeleteCall) Context(ctx context.Context) *VpnTunnelsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnTunnelsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnTunnelsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnTunnels/{vpnTunnel}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"region":    c.region,
		"vpnTunnel": c.vpnTunnel,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnTunnels.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VpnTunnelsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the specified VpnTunnel resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.vpnTunnels.delete",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "vpnTunnel"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "vpnTunnel": {
	//       "description": "Name of the VpnTunnel resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnTunnels/{vpnTunnel}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.vpnTunnels.get":

type VpnTunnelsGetCall struct {
	s            *Service
	project      string
	region       string
	vpnTunnel    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified VpnTunnel resource. Gets a list of
// available VPN tunnels by making a list() request. (==
// suppress_warning http-rest-shadowed ==)
func (r *VpnTunnelsService) Get(project string, region string, vpnTunnel string) *VpnTunnelsGetCall {
	c := &VpnTunnelsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.vpnTunnel = vpnTunnel
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnTunnelsGetCall) Fields(s ...googleapi.Field) *VpnTunnelsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *VpnTunnelsGetCall) IfNoneMatch(entityTag string) *VpnTunnelsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnTunnelsGetCall) Context(ctx context.Context) *VpnTunnelsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnTunnelsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnTunnelsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnTunnels/{vpnTunnel}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"region":    c.region,
		"vpnTunnel": c.vpnTunnel,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnTunnels.get" call.
// Exactly one of *VpnTunnel or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *VpnTunnel.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VpnTunnelsGetCall) Do(opts ...googleapi.CallOption) (*VpnTunnel, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VpnTunnel{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified VpnTunnel resource. Gets a list of available VPN tunnels by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.vpnTunnels.get",
	//   "parameterOrder": [
	//     "project",
	//     "region",
	//     "vpnTunnel"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "vpnTunnel": {
	//       "description": "Name of the VpnTunnel resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnTunnels/{vpnTunnel}",
	//   "response": {
	//     "$ref": "VpnTunnel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.vpnTunnels.insert":

type VpnTunnelsInsertCall struct {
	s          *Service
	project    string
	region     string
	vpntunnel  *VpnTunnel
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a VpnTunnel resource in the specified project and
// region using the data included in the request. (== suppress_warning
// http-rest-shadowed ==)
func (r *VpnTunnelsService) Insert(project string, region string, vpntunnel *VpnTunnel) *VpnTunnelsInsertCall {
	c := &VpnTunnelsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	c.vpntunnel = vpntunnel
	return c
}

// RequestId sets the optional parameter "requestId": An optional
// request ID to identify requests. Specify a unique request ID so that
// if you must retry your request, the server will know to ignore the
// request if it has already been completed.
//
// For example, consider a situation where you make an initial request
// and the request times out. If you make the request again with the
// same request ID, the server can check if original operation with the
// same request ID was received, and if so, will ignore the second
// request. This prevents clients from accidentally creating duplicate
// commitments.
//
// The request ID must be a valid UUID with the exception that zero UUID
// is not supported (00000000-0000-0000-0000-000000000000).
func (c *VpnTunnelsInsertCall) RequestId(requestId string) *VpnTunnelsInsertCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnTunnelsInsertCall) Fields(s ...googleapi.Field) *VpnTunnelsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnTunnelsInsertCall) Context(ctx context.Context) *VpnTunnelsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnTunnelsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnTunnelsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.vpntunnel)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnTunnels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnTunnels.insert" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VpnTunnelsInsertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a VpnTunnel resource in the specified project and region using the data included in the request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "POST",
	//   "id": "compute.vpnTunnels.insert",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "An optional request ID to identify requests. Specify a unique request ID so that if you must retry your request, the server will know to ignore the request if it has already been completed.\n\nFor example, consider a situation where you make an initial request and the request times out. If you make the request again with the same request ID, the server can check if original operation with the same request ID was received, and if so, will ignore the second request. This prevents clients from accidentally creating duplicate commitments.\n\nThe request ID must be a valid UUID with the exception that zero UUID is not supported (00000000-0000-0000-0000-000000000000).",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnTunnels",
	//   "request": {
	//     "$ref": "VpnTunnel"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.vpnTunnels.list":

type VpnTunnelsListCall struct {
	s            *Service
	project      string
	region       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of VpnTunnel resources contained in the
// specified project and region. (== suppress_warning http-rest-shadowed
// ==)
func (r *VpnTunnelsService) List(project string, region string) *VpnTunnelsListCall {
	c := &VpnTunnelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.region = region
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *VpnTunnelsListCall) Filter(filter string) *VpnTunnelsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *VpnTunnelsListCall) MaxResults(maxResults int64) *VpnTunnelsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *VpnTunnelsListCall) OrderBy(orderBy string) *VpnTunnelsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *VpnTunnelsListCall) PageToken(pageToken string) *VpnTunnelsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VpnTunnelsListCall) Fields(s ...googleapi.Field) *VpnTunnelsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *VpnTunnelsListCall) IfNoneMatch(entityTag string) *VpnTunnelsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VpnTunnelsListCall) Context(ctx context.Context) *VpnTunnelsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VpnTunnelsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VpnTunnelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/vpnTunnels")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"region":  c.region,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.vpnTunnels.list" call.
// Exactly one of *VpnTunnelList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *VpnTunnelList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VpnTunnelsListCall) Do(opts ...googleapi.CallOption) (*VpnTunnelList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VpnTunnelList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of VpnTunnel resources contained in the specified project and region. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.vpnTunnels.list",
	//   "parameterOrder": [
	//     "project",
	//     "region"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "region": {
	//       "description": "Name of the region for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/regions/{region}/vpnTunnels",
	//   "response": {
	//     "$ref": "VpnTunnelList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *VpnTunnelsListCall) Pages(ctx context.Context, f func(*VpnTunnelList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.zoneOperations.delete":

type ZoneOperationsDeleteCall struct {
	s          *Service
	project    string
	zone       string
	operation  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified zone-specific Operations resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/zoneOperations/delete
func (r *ZoneOperationsService) Delete(project string, zone string, operation string) *ZoneOperationsDeleteCall {
	c := &ZoneOperationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.operation = operation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ZoneOperationsDeleteCall) Fields(s ...googleapi.Field) *ZoneOperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ZoneOperationsDeleteCall) Context(ctx context.Context) *ZoneOperationsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ZoneOperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ZoneOperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/operations/{operation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"operation": c.operation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.zoneOperations.delete" call.
func (c *ZoneOperationsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes the specified zone-specific Operations resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "DELETE",
	//   "id": "compute.zoneOperations.delete",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "operation"
	//   ],
	//   "parameters": {
	//     "operation": {
	//       "description": "Name of the Operations resource to delete.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/operations/{operation}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute"
	//   ]
	// }

}

// method id "compute.zoneOperations.get":

type ZoneOperationsGetCall struct {
	s            *Service
	project      string
	zone         string
	operation    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified zone-specific Operations resource. (==
// suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/zoneOperations/get
func (r *ZoneOperationsService) Get(project string, zone string, operation string) *ZoneOperationsGetCall {
	c := &ZoneOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	c.operation = operation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ZoneOperationsGetCall) Fields(s ...googleapi.Field) *ZoneOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ZoneOperationsGetCall) IfNoneMatch(entityTag string) *ZoneOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ZoneOperationsGetCall) Context(ctx context.Context) *ZoneOperationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ZoneOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ZoneOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/operations/{operation}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project":   c.project,
		"zone":      c.zone,
		"operation": c.operation,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.zoneOperations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ZoneOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the specified zone-specific Operations resource. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.zoneOperations.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone",
	//     "operation"
	//   ],
	//   "parameters": {
	//     "operation": {
	//       "description": "Name of the Operations resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for this request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/operations/{operation}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.zoneOperations.list":

type ZoneOperationsListCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of Operation resources contained within the
// specified zone. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/zoneOperations/list
func (r *ZoneOperationsService) List(project string, zone string) *ZoneOperationsListCall {
	c := &ZoneOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ZoneOperationsListCall) Filter(filter string) *ZoneOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ZoneOperationsListCall) MaxResults(maxResults int64) *ZoneOperationsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ZoneOperationsListCall) OrderBy(orderBy string) *ZoneOperationsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ZoneOperationsListCall) PageToken(pageToken string) *ZoneOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ZoneOperationsListCall) Fields(s ...googleapi.Field) *ZoneOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ZoneOperationsListCall) IfNoneMatch(entityTag string) *ZoneOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ZoneOperationsListCall) Context(ctx context.Context) *ZoneOperationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ZoneOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ZoneOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.zoneOperations.list" call.
// Exactly one of *OperationList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *OperationList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ZoneOperationsListCall) Do(opts ...googleapi.CallOption) (*OperationList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperationList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of Operation resources contained within the specified zone. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.zoneOperations.list",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone for request.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}/operations",
	//   "response": {
	//     "$ref": "OperationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ZoneOperationsListCall) Pages(ctx context.Context, f func(*OperationList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "compute.zones.get":

type ZonesGetCall struct {
	s            *Service
	project      string
	zone         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the specified Zone resource. Gets a list of available
// zones by making a list() request. (== suppress_warning
// http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/zones/get
func (r *ZonesService) Get(project string, zone string) *ZonesGetCall {
	c := &ZonesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	c.zone = zone
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ZonesGetCall) Fields(s ...googleapi.Field) *ZonesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ZonesGetCall) IfNoneMatch(entityTag string) *ZonesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ZonesGetCall) Context(ctx context.Context) *ZonesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ZonesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ZonesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
		"zone":    c.zone,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.zones.get" call.
// Exactly one of *Zone or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Zone.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ZonesGetCall) Do(opts ...googleapi.CallOption) (*Zone, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Zone{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified Zone resource. Gets a list of available zones by making a list() request. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.zones.get",
	//   "parameterOrder": [
	//     "project",
	//     "zone"
	//   ],
	//   "parameters": {
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "zone": {
	//       "description": "Name of the zone resource to return.",
	//       "location": "path",
	//       "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones/{zone}",
	//   "response": {
	//     "$ref": "Zone"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// method id "compute.zones.list":

type ZonesListCall struct {
	s            *Service
	project      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves the list of Zone resources available to the specified
// project. (== suppress_warning http-rest-shadowed ==)
// For details, see https://cloud.google.com/compute/docs/reference/latest/zones/list
func (r *ZonesService) List(project string) *ZonesListCall {
	c := &ZonesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.project = project
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. The comparison operator must be either =, !=, >, or <.
//
// For example, if you are filtering Compute Engine instances, you can
// exclude instances named example-instance by specifying name !=
// example-instance.
//
// You can also filter nested fields. For example, you could specify
// scheduling.automaticRestart = false to include instances only if they
// are not scheduled for automatic restarts. You can use filtering on
// nested fields to filter based on resource labels.
//
// To filter on multiple expressions, provide each separate expression
// within parentheses. For example, (scheduling.automaticRestart = true)
// (cpuPlatform = "Intel Skylake"). By default, each expression is an
// AND expression. However, you can include AND and OR expressions
// explicitly. For example, (cpuPlatform = "Intel Skylake") OR
// (cpuPlatform = "Intel Broadwell") AND (scheduling.automaticRestart =
// true).
func (c *ZonesListCall) Filter(filter string) *ZonesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results per page that should be returned. If the number of
// available results is larger than maxResults, Compute Engine returns a
// nextPageToken that can be used to get the next page of results in
// subsequent list requests. Acceptable values are 0 to 500, inclusive.
// (Default: 500)
func (c *ZonesListCall) MaxResults(maxResults int64) *ZonesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderBy sets the optional parameter "orderBy": Sorts list results by
// a certain order. By default, results are returned in alphanumerical
// order based on the resource name.
//
// You can also sort results in descending order based on the creation
// timestamp using orderBy="creationTimestamp desc". This sorts results
// based on the creationTimestamp field in reverse chronological order
// (newest result first). Use this to sort resources like operations so
// that the newest operation is returned first.
//
// Currently, only sorting by name or creationTimestamp desc is
// supported.
func (c *ZonesListCall) OrderBy(orderBy string) *ZonesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageToken sets the optional parameter "pageToken": Specifies a page
// token to use. Set pageToken to the nextPageToken returned by a
// previous list request to get the next page of results.
func (c *ZonesListCall) PageToken(pageToken string) *ZonesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ZonesListCall) Fields(s ...googleapi.Field) *ZonesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ZonesListCall) IfNoneMatch(entityTag string) *ZonesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ZonesListCall) Context(ctx context.Context) *ZonesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ZonesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ZonesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191204")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"project": c.project,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "compute.zones.list" call.
// Exactly one of *ZoneList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *ZoneList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ZonesListCall) Do(opts ...googleapi.CallOption) (*ZoneList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ZoneList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of Zone resources available to the specified project. (== suppress_warning http-rest-shadowed ==)",
	//   "httpMethod": "GET",
	//   "id": "compute.zones.list",
	//   "parameterOrder": [
	//     "project"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. The comparison operator must be either =, !=, \u003e, or \u003c.\n\nFor example, if you are filtering Compute Engine instances, you can exclude instances named example-instance by specifying name != example-instance.\n\nYou can also filter nested fields. For example, you could specify scheduling.automaticRestart = false to include instances only if they are not scheduled for automatic restarts. You can use filtering on nested fields to filter based on resource labels.\n\nTo filter on multiple expressions, provide each separate expression within parentheses. For example, (scheduling.automaticRestart = true) (cpuPlatform = \"Intel Skylake\"). By default, each expression is an AND expression. However, you can include AND and OR expressions explicitly. For example, (cpuPlatform = \"Intel Skylake\") OR (cpuPlatform = \"Intel Broadwell\") AND (scheduling.automaticRestart = true).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The maximum number of results per page that should be returned. If the number of available results is larger than maxResults, Compute Engine returns a nextPageToken that can be used to get the next page of results in subsequent list requests. Acceptable values are 0 to 500, inclusive. (Default: 500)",
	//       "format": "uint32",
	//       "location": "query",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderBy": {
	//       "description": "Sorts list results by a certain order. By default, results are returned in alphanumerical order based on the resource name.\n\nYou can also sort results in descending order based on the creation timestamp using orderBy=\"creationTimestamp desc\". This sorts results based on the creationTimestamp field in reverse chronological order (newest result first). Use this to sort resources like operations so that the newest operation is returned first.\n\nCurrently, only sorting by name or creationTimestamp desc is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Specifies a page token to use. Set pageToken to the nextPageToken returned by a previous list request to get the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "project": {
	//       "description": "Project ID for this request.",
	//       "location": "path",
	//       "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{project}/zones",
	//   "response": {
	//     "$ref": "ZoneList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/compute.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ZonesListCall) Pages(ctx context.Context, f func(*ZoneList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}
