// Copyright 2020 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 serviceusage provides access to the Service Usage API.
//
// For product documentation, see: https://cloud.google.com/service-usage/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/serviceusage/v1beta1"
//   ...
//   ctx := context.Background()
//   serviceusageService, err := serviceusage.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:
//
//   serviceusageService, err := serviceusage.NewService(ctx, option.WithScopes(serviceusage.ServiceManagementScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   serviceusageService, err := serviceusage.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, ...)
//   serviceusageService, err := serviceusage.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package serviceusage // import "google.golang.org/api/serviceusage/v1beta1"

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"
	internaloption "google.golang.org/api/option/internaloption"
	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
var _ = internaloption.WithDefaultEndpoint

const apiId = "serviceusage:v1beta1"
const apiName = "serviceusage"
const apiVersion = "v1beta1"
const basePath = "https://serviceusage.googleapis.com/"
const mtlsBasePath = "https://serviceusage.mtls.googleapis.com/"

// 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 your data across Google Cloud Platform services
	CloudPlatformReadOnlyScope = "https://www.googleapis.com/auth/cloud-platform.read-only"

	// Manage your Google API service configuration
	ServiceManagementScope = "https://www.googleapis.com/auth/service.management"
)

// NewService creates a new APIService.
func NewService(ctx context.Context, opts ...option.ClientOption) (*APIService, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
		"https://www.googleapis.com/auth/cloud-platform.read-only",
		"https://www.googleapis.com/auth/service.management",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	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 APIService. 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) (*APIService, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &APIService{client: client, BasePath: basePath}
	s.Operations = NewOperationsService(s)
	s.Services = NewServicesService(s)
	return s, nil
}

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

	Operations *OperationsService

	Services *ServicesService
}

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

func NewOperationsService(s *APIService) *OperationsService {
	rs := &OperationsService{s: s}
	return rs
}

type OperationsService struct {
	s *APIService
}

func NewServicesService(s *APIService) *ServicesService {
	rs := &ServicesService{s: s}
	rs.ConsumerQuotaMetrics = NewServicesConsumerQuotaMetricsService(s)
	return rs
}

type ServicesService struct {
	s *APIService

	ConsumerQuotaMetrics *ServicesConsumerQuotaMetricsService
}

func NewServicesConsumerQuotaMetricsService(s *APIService) *ServicesConsumerQuotaMetricsService {
	rs := &ServicesConsumerQuotaMetricsService{s: s}
	rs.Limits = NewServicesConsumerQuotaMetricsLimitsService(s)
	return rs
}

type ServicesConsumerQuotaMetricsService struct {
	s *APIService

	Limits *ServicesConsumerQuotaMetricsLimitsService
}

func NewServicesConsumerQuotaMetricsLimitsService(s *APIService) *ServicesConsumerQuotaMetricsLimitsService {
	rs := &ServicesConsumerQuotaMetricsLimitsService{s: s}
	rs.AdminOverrides = NewServicesConsumerQuotaMetricsLimitsAdminOverridesService(s)
	rs.ConsumerOverrides = NewServicesConsumerQuotaMetricsLimitsConsumerOverridesService(s)
	return rs
}

type ServicesConsumerQuotaMetricsLimitsService struct {
	s *APIService

	AdminOverrides *ServicesConsumerQuotaMetricsLimitsAdminOverridesService

	ConsumerOverrides *ServicesConsumerQuotaMetricsLimitsConsumerOverridesService
}

func NewServicesConsumerQuotaMetricsLimitsAdminOverridesService(s *APIService) *ServicesConsumerQuotaMetricsLimitsAdminOverridesService {
	rs := &ServicesConsumerQuotaMetricsLimitsAdminOverridesService{s: s}
	return rs
}

type ServicesConsumerQuotaMetricsLimitsAdminOverridesService struct {
	s *APIService
}

func NewServicesConsumerQuotaMetricsLimitsConsumerOverridesService(s *APIService) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesService {
	rs := &ServicesConsumerQuotaMetricsLimitsConsumerOverridesService{s: s}
	return rs
}

type ServicesConsumerQuotaMetricsLimitsConsumerOverridesService struct {
	s *APIService
}

// AdminQuotaPolicy: Quota policy created by quota administrator.
type AdminQuotaPolicy struct {
	// Container: The cloud resource container at which the quota policy is
	// created. The
	// format is {container_type}/{container_number}
	Container string `json:"container,omitempty"`

	// Dimensions:
	// If this map is nonempty, then this policy applies only to specific
	// values
	// for dimensions defined in the limit unit.
	//
	// For example, an policy on a limit with the unit
	// 1/{project}/{region}
	// could contain an entry with the key "region" and the value
	// "us-east-1";
	// the policy is only applied to quota consumed in that region.
	//
	// This map has the following restrictions:
	//
	// *   If "region" appears as a key, its value must be a valid Cloud
	// region.
	// *   If "zone" appears as a key, its value must be a valid Cloud
	// zone.
	// *   Keys other than "region" or "zone" are not valid.
	Dimensions map[string]string `json:"dimensions,omitempty"`

	// Metric: The name of the metric to which this policy applies.
	//
	// An example name would be:
	// `compute.googleapis.com/cpus`
	Metric string `json:"metric,omitempty"`

	// Name: The resource name of the policy.
	// This name is generated by the server when the policy is
	// created.
	//
	// Example names would
	// be:
	// `organizations/123/services/compute.googleapis.com/consumerQuotaMe
	// trics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/adminQu
	// otaPolicies/4a3f2c1d`
	Name string `json:"name,omitempty"`

	// PolicyValue: The quota policy value.
	// Can be any nonnegative integer, or -1 (unlimited quota).
	PolicyValue int64 `json:"policyValue,omitempty,string"`

	// Unit: The limit unit of the limit to which this policy applies.
	//
	// An example unit would be:
	// `1/{project}/{region}`
	// Note that `{project}` and `{region}` are not placeholders in this
	// example;
	// the literal characters `{` and `}` occur in the string.
	Unit string `json:"unit,omitempty"`

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

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

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

// Api: Api is a light-weight descriptor for an API
// Interface.
//
// Interfaces are also described as "protocol buffer services" in some
// contexts,
// such as by the "service" keyword in a .proto file, but they are
// different
// from API Services, which represent a concrete implementation of an
// interface
// as opposed to simply a description of methods and bindings. They are
// also
// sometimes simply referred to as "APIs" in other contexts, such as the
// name of
// this message itself. See
// https://cloud.google.com/apis/design/glossary for
// detailed terminology.
type Api struct {
	// Methods: The methods of this interface, in unspecified order.
	Methods []*Method `json:"methods,omitempty"`

	// Mixins: Included interfaces. See Mixin.
	Mixins []*Mixin `json:"mixins,omitempty"`

	// Name: The fully qualified name of this interface, including package
	// name
	// followed by the interface's simple name.
	Name string `json:"name,omitempty"`

	// Options: Any metadata attached to the interface.
	Options []*Option `json:"options,omitempty"`

	// SourceContext: Source context for the protocol buffer service
	// represented by this
	// message.
	SourceContext *SourceContext `json:"sourceContext,omitempty"`

	// Syntax: The source syntax of the service.
	//
	// Possible values:
	//   "SYNTAX_PROTO2" - Syntax `proto2`.
	//   "SYNTAX_PROTO3" - Syntax `proto3`.
	Syntax string `json:"syntax,omitempty"`

	// Version: A version string for this interface. If specified, must have
	// the form
	// `major-version.minor-version`, as in `1.10`. If the minor version
	// is
	// omitted, it defaults to zero. If the entire version field is empty,
	// the
	// major version is derived from the package name, as outlined below. If
	// the
	// field is not empty, the version in the package name will be verified
	// to be
	// consistent with what is provided here.
	//
	// The versioning schema uses [semantic
	// versioning](http://semver.org) where the major version
	// number
	// indicates a breaking change and the minor version an
	// additive,
	// non-breaking change. Both version numbers are signals to users
	// what to expect from different versions, and should be
	// carefully
	// chosen based on the product plan.
	//
	// The major version is also reflected in the package name of
	// the
	// interface, which must end in `v<major-version>`, as
	// in
	// `google.feature.v1`. For major versions 0 and 1, the suffix can
	// be omitted. Zero major versions must only be used for
	// experimental, non-GA interfaces.
	//
	Version string `json:"version,omitempty"`

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

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

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

// AuthProvider: Configuration for an authentication provider, including
// support for
// [JSON Web
// Token
// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-tok
// en-32).
type AuthProvider struct {
	// Audiences: The list of
	// JWT
	// [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-
	// token-32#section-4.1.3).
	// that are allowed to access. A JWT containing any of these audiences
	// will
	// be accepted. When this setting is absent, JWTs with audiences:
	//   - "https://[service.name]/[google.protobuf.Api.name]"
	//   - "https://[service.name]/"
	// will be accepted.
	// For example, if no audiences are in the setting, LibraryService API
	// will
	// accept JWTs with the following audiences:
	//   -
	//
	// https://library-example.googleapis.com/google.example.library.v1.LibraryService
	//   - https://library-example.googleapis.com/
	//
	// Example:
	//
	//     audiences: bookstore_android.apps.googleusercontent.com,
	//                bookstore_web.apps.googleusercontent.com
	Audiences string `json:"audiences,omitempty"`

	// AuthorizationUrl: Redirect URL if JWT token is required but not
	// present or is expired.
	// Implement authorizationUrl of securityDefinitions in OpenAPI spec.
	AuthorizationUrl string `json:"authorizationUrl,omitempty"`

	// Id: The unique identifier of the auth provider. It will be referred
	// to by
	// `AuthRequirement.provider_id`.
	//
	// Example: "bookstore_auth".
	Id string `json:"id,omitempty"`

	// Issuer: Identifies the principal that issued the JWT.
	// See
	// https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#sec
	// tion-4.1.1
	// Usually a URL or an email address.
	//
	// Example: https://securetoken.google.com
	// Example: 1234567-compute@developer.gserviceaccount.com
	Issuer string `json:"issuer,omitempty"`

	// JwksUri: URL of the provider's public key set to validate signature
	// of the JWT.
	// See
	// [OpenID
	// Discovery](https://openid.net/specs/openid-connect-discove
	// ry-1_0.html#ProviderMetadata).
	// Optional if the key set document:
	//  - can be retrieved from
	//    [OpenID
	//
	// Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html
	// of
	//    the issuer.
	//  - can be inferred from the email domain of the issuer (e.g. a
	// Google
	//  service account).
	//
	// Example: https://www.googleapis.com/oauth2/v1/certs
	JwksUri string `json:"jwksUri,omitempty"`

	// JwtLocations: Defines the locations to extract the JWT.
	//
	// JWT locations can be either from HTTP headers or URL query
	// parameters.
	// The rule is that the first match wins. The checking order is:
	// checking
	// all headers first, then URL query parameters.
	//
	// If not specified,  default to use following 3 locations:
	//    1) Authorization: Bearer
	//    2) x-goog-iap-jwt-assertion
	//    3) access_token query parameter
	//
	// Default locations can be specified as followings:
	//    jwt_locations:
	//    - header: Authorization
	//      value_prefix: "Bearer "
	//    - header: x-goog-iap-jwt-assertion
	//    - query: access_token
	JwtLocations []*JwtLocation `json:"jwtLocations,omitempty"`

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

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

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

// AuthRequirement: User-defined authentication requirements, including
// support for
// [JSON Web
// Token
// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-tok
// en-32).
type AuthRequirement struct {
	// Audiences: NOTE: This will be deprecated soon, once
	// AuthProvider.audiences is
	// implemented and accepted in all the runtime components.
	//
	// The list of
	// JWT
	// [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-
	// token-32#section-4.1.3).
	// that are allowed to access. A JWT containing any of these audiences
	// will
	// be accepted. When this setting is absent, only JWTs with
	// audience
	// "https://Service_name/API_name"
	// will be accepted. For example, if no audiences are in the
	// setting,
	// LibraryService API will only accept JWTs with the following
	// audience
	// "https://library-example.googleapis.com/google.example.librar
	// y.v1.LibraryService".
	//
	// Example:
	//
	//     audiences: bookstore_android.apps.googleusercontent.com,
	//                bookstore_web.apps.googleusercontent.com
	Audiences string `json:"audiences,omitempty"`

	// ProviderId: id from authentication provider.
	//
	// Example:
	//
	//     provider_id: bookstore_auth
	ProviderId string `json:"providerId,omitempty"`

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

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

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

// Authentication: `Authentication` defines the authentication
// configuration for an API.
//
// Example for an API targeted for external use:
//
//     name: calendar.googleapis.com
//     authentication:
//       providers:
//       - id: google_calendar_auth
//         jwks_uri: https://www.googleapis.com/oauth2/v1/certs
//         issuer: https://securetoken.google.com
//       rules:
//       - selector: "*"
//         requirements:
//           provider_id: google_calendar_auth
type Authentication struct {
	// Providers: Defines a set of authentication providers that a service
	// supports.
	Providers []*AuthProvider `json:"providers,omitempty"`

	// Rules: A list of authentication rules that apply to individual API
	// methods.
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*AuthenticationRule `json:"rules,omitempty"`

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

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

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

// AuthenticationRule: Authentication rules for the service.
//
// By default, if a method has any authentication requirements, every
// request
// must include a valid credential matching one of the
// requirements.
// It's an error to include more than one kind of credential in a
// single
// request.
//
// If a method doesn't have any auth requirements, request credentials
// will be
// ignored.
type AuthenticationRule struct {
	// AllowWithoutCredential: If true, the service accepts API keys without
	// any other credential.
	AllowWithoutCredential bool `json:"allowWithoutCredential,omitempty"`

	// Oauth: The requirements for OAuth credentials.
	Oauth *OAuthRequirements `json:"oauth,omitempty"`

	// Requirements: Requirements for additional authentication providers.
	Requirements []*AuthRequirement `json:"requirements,omitempty"`

	// Selector: Selects the methods to which this rule applies.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

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

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

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

// Backend: `Backend` defines the backend configuration for a service.
type Backend struct {
	// Rules: A list of API backend rules that apply to individual API
	// methods.
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*BackendRule `json:"rules,omitempty"`

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

	// NullFields is a list of field names (e.g. "Rules") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field 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)
}

// BackendRule: A backend rule provides configuration for an individual
// API element.
type BackendRule struct {
	// Address: The address of the API backend.
	//
	// The scheme is used to determine the backend protocol and
	// security.
	// The following schemes are accepted:
	//
	//    SCHEME        PROTOCOL    SECURITY
	//    http://       HTTP        None
	//    https://      HTTP        TLS
	//    grpc://       gRPC        None
	//    grpcs://      gRPC        TLS
	//
	// It is recommended to explicitly include a scheme. Leaving out the
	// scheme
	// may cause constrasting behaviors across platforms.
	//
	// If the port is unspecified, the default is:
	// - 80 for schemes without TLS
	// - 443 for schemes with TLS
	//
	// For HTTP backends, use protocol
	// to specify the protocol version.
	Address string `json:"address,omitempty"`

	// Deadline: The number of seconds to wait for a response from a
	// request. The default
	// varies based on the request protocol and deployment environment.
	Deadline float64 `json:"deadline,omitempty"`

	// DisableAuth: When disable_auth is true, a JWT ID token won't be
	// generated and the
	// original "Authorization" HTTP header will be preserved. If the header
	// is
	// used to carry the original token and is expected by the backend,
	// this
	// field must be set to true to preserve the header.
	DisableAuth bool `json:"disableAuth,omitempty"`

	// JwtAudience: The JWT audience is used when generating a JWT ID token
	// for the backend.
	// This ID token will be added in the HTTP "authorization" header, and
	// sent
	// to the backend.
	JwtAudience string `json:"jwtAudience,omitempty"`

	// MinDeadline: Minimum deadline in seconds needed for this method.
	// Calls having deadline
	// value lower than this will be rejected.
	MinDeadline float64 `json:"minDeadline,omitempty"`

	// OperationDeadline: The number of seconds to wait for the completion
	// of a long running
	// operation. The default is no deadline.
	OperationDeadline float64 `json:"operationDeadline,omitempty"`

	// Possible values:
	//   "PATH_TRANSLATION_UNSPECIFIED"
	//   "CONSTANT_ADDRESS" - Use the backend address as-is, with no
	// modification to the path. If the
	// URL pattern contains variables, the variable names and values will
	// be
	// appended to the query string. If a query string parameter and a
	// URL
	// pattern variable have the same name, this may result in duplicate
	// keys in
	// the query string.
	//
	// # Examples
	//
	// Given the following operation config:
	//
	//     Method path:        /api/company/{cid}/user/{uid}
	//     Backend address:
	// https://example.cloudfunctions.net/getUser
	//
	// Requests to the following request paths will call the backend at
	// the
	// translated path:
	//
	//     Request path: /api/company/widgetworks/user/johndoe
	//     Translated:
	//
	// https://example.cloudfunctions.net/getUser?cid=widgetworks&uid=johndoe
	//
	//     Request path: /api/company/widgetworks/user/johndoe?timezone=EST
	//     Translated:
	//
	// https://example.cloudfunctions.net/getUser?timezone=EST&cid=widgetworks&uid=johndoe
	//   "APPEND_PATH_TO_ADDRESS" - The request path will be appended to the
	// backend address.
	//
	// # Examples
	//
	// Given the following operation config:
	//
	//     Method path:        /api/company/{cid}/user/{uid}
	//     Backend address:    https://example.appspot.com
	//
	// Requests to the following request paths will call the backend at
	// the
	// translated path:
	//
	//     Request path: /api/company/widgetworks/user/johndoe
	//     Translated:
	//
	// https://example.appspot.com/api/company/widgetworks/user/johndoe
	//
	//     Request path: /api/company/widgetworks/user/johndoe?timezone=EST
	//     Translated:
	//
	// https://example.appspot.com/api/company/widgetworks/user/johndoe?timezone=EST
	PathTranslation string `json:"pathTranslation,omitempty"`

	// Protocol: The protocol used for sending a request to the backend.
	// The supported values are "http/1.1" and "h2".
	//
	// The default value is inferred from the scheme in the
	// address field:
	//
	//    SCHEME        PROTOCOL
	//    http://       http/1.1
	//    https://      http/1.1
	//    grpc://       h2
	//    grpcs://      h2
	//
	// For secure HTTP backends (https://) that support HTTP/2, set this
	// field
	// to "h2" for improved performance.
	//
	// Configuring this field to non-default values is only supported for
	// secure
	// HTTP backends. This field will be ignored for all other
	// backends.
	//
	// See
	// https://www.iana.org/assignments/tls-extensiontype-valu
	// es/tls-extensiontype-values.xhtml#alpn-protocol-ids
	// for more details on the supported values.
	Protocol string `json:"protocol,omitempty"`

	// Selector: Selects the methods to which this rule applies.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

	// 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 *BackendRule) MarshalJSON() ([]byte, error) {
	type NoMethod BackendRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *BackendRule) UnmarshalJSON(data []byte) error {
	type NoMethod BackendRule
	var s1 struct {
		Deadline          gensupport.JSONFloat64 `json:"deadline"`
		MinDeadline       gensupport.JSONFloat64 `json:"minDeadline"`
		OperationDeadline gensupport.JSONFloat64 `json:"operationDeadline"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Deadline = float64(s1.Deadline)
	s.MinDeadline = float64(s1.MinDeadline)
	s.OperationDeadline = float64(s1.OperationDeadline)
	return nil
}

// BatchCreateAdminOverridesResponse: Response message for
// BatchCreateAdminOverrides
type BatchCreateAdminOverridesResponse struct {
	// Overrides: The overrides that were created.
	Overrides []*QuotaOverride `json:"overrides,omitempty"`

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

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

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

// BatchCreateConsumerOverridesResponse: Response message for
// BatchCreateConsumerOverrides
type BatchCreateConsumerOverridesResponse struct {
	// Overrides: The overrides that were created.
	Overrides []*QuotaOverride `json:"overrides,omitempty"`

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

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

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

// BatchEnableServicesRequest: Request message for the
// `BatchEnableServices` method.
type BatchEnableServicesRequest struct {
	// ServiceIds: The identifiers of the services to enable on the
	// project.
	//
	// A valid identifier would be:
	// serviceusage.googleapis.com
	//
	// Enabling services requires that each service is public or is shared
	// with
	// the user enabling the service.
	//
	// Two or more services must be specified. To enable a single
	// service,
	// use the `EnableService` method instead.
	//
	// A single request can enable a maximum of 20 services at a time. If
	// more
	// than 20 services are specified, the request will fail, and no state
	// changes
	// will occur.
	ServiceIds []string `json:"serviceIds,omitempty"`

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

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

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

// BatchEnableServicesResponse: Response message for the
// `BatchEnableServices` method.
// This response message is assigned to the `response` field of the
// returned
// Operation when that operation is done.
type BatchEnableServicesResponse struct {
	// Failures: If allow_partial_success is true, and one or more services
	// could not be
	// enabled, this field contains the details about each failure.
	Failures []*EnableFailure `json:"failures,omitempty"`

	// Services: The new state of the services after enabling.
	Services []*GoogleApiServiceusageV1Service `json:"services,omitempty"`

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

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

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

// Billing: Billing related configuration of the service.
//
// The following example shows how to configure monitored resources and
// metrics
// for billing, `consumer_destinations` is the only supported
// destination and
// the monitored resources need at least one label
// key
// `cloud.googleapis.com/location` to indicate the location of the
// billing
// usage, using different monitored resources between monitoring and
// billing is
// recommended so they can be evolved independently:
//
//
//     monitored_resources:
//     - type: library.googleapis.com/billing_branch
//       labels:
//       - key: cloud.googleapis.com/location
//         description: |
//           Predefined label to support billing location restriction.
//       - key: city
//         description: |
//           Custom label to define the city where the library branch is
// located
//           in.
//       - key: name
//         description: Custom label to define the name of the library
// branch.
//     metrics:
//     - name: library.googleapis.com/book/borrowed_count
//       metric_kind: DELTA
//       value_type: INT64
//       unit: "1"
//     billing:
//       consumer_destinations:
//       - monitored_resource: library.googleapis.com/billing_branch
//         metrics:
//         - library.googleapis.com/book/borrowed_count
type Billing struct {
	// ConsumerDestinations: Billing configurations for sending metrics to
	// the consumer project.
	// There can be multiple consumer destinations per service, each one
	// must have
	// a different monitored resource type. A metric can be used in at
	// most
	// one consumer destination.
	ConsumerDestinations []*BillingDestination `json:"consumerDestinations,omitempty"`

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

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

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

// BillingDestination: Configuration of a specific billing destination
// (Currently only support
// bill against consumer project).
type BillingDestination struct {
	// Metrics: Names of the metrics to report to this billing
	// destination.
	// Each name must be defined in Service.metrics section.
	Metrics []string `json:"metrics,omitempty"`

	// MonitoredResource: The monitored resource type. The type must be
	// defined in
	// Service.monitored_resources section.
	MonitoredResource string `json:"monitoredResource,omitempty"`

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

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

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

// ConsumerQuotaLimit: Consumer quota settings for a quota limit.
type ConsumerQuotaLimit struct {
	// AllowsAdminOverrides: Whether admin overrides are allowed on this
	// limit
	AllowsAdminOverrides bool `json:"allowsAdminOverrides,omitempty"`

	// IsPrecise: Whether this limit is precise or imprecise.
	IsPrecise bool `json:"isPrecise,omitempty"`

	// Metric: The name of the parent metric of this limit.
	//
	// An example name would be:
	// `compute.googleapis.com/cpus`
	Metric string `json:"metric,omitempty"`

	// Name: The resource name of the quota limit.
	//
	// An example name would
	// be:
	// `projects/123/services/compute.googleapis.com/consumerQuotaMetrics
	// /compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion`
	//
	// The resource name is intended to be opaque and should not be parsed
	// for
	// its component strings, since its representation could change in the
	// future.
	Name string `json:"name,omitempty"`

	// QuotaBuckets: Summary of the enforced quota buckets, organized by
	// quota dimension,
	// ordered from least specific to most specific (for example, the
	// global
	// default bucket, with no quota dimensions, will always appear first).
	QuotaBuckets []*QuotaBucket `json:"quotaBuckets,omitempty"`

	// Unit: The limit unit.
	//
	// An example unit would be
	// `1/{project}/{region}`
	// Note that `{project}` and `{region}` are not placeholders in this
	// example;
	// the literal characters `{` and `}` occur in the string.
	Unit string `json:"unit,omitempty"`

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

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

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

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

// ConsumerQuotaMetric: Consumer quota settings for a quota metric.
type ConsumerQuotaMetric struct {
	// ConsumerQuotaLimits: The consumer quota for each quota limit defined
	// on the metric.
	ConsumerQuotaLimits []*ConsumerQuotaLimit `json:"consumerQuotaLimits,omitempty"`

	// DisplayName: The display name of the metric.
	//
	// An example name would be:
	// "CPUs"
	DisplayName string `json:"displayName,omitempty"`

	// Metric: The name of the metric.
	//
	// An example name would be:
	// `compute.googleapis.com/cpus`
	Metric string `json:"metric,omitempty"`

	// Name: The resource name of the quota settings on this metric for this
	// consumer.
	//
	// An example name would
	// be:
	// `projects/123/services/compute.googleapis.com/consumerQuotaMetrics
	// /compute.googleapis.com%2Fcpus
	//
	// The resource name is intended to be opaque and should not be parsed
	// for
	// its component strings, since its representation could change in the
	// future.
	Name string `json:"name,omitempty"`

	// Unit: The units in which the metric value is reported.
	Unit string `json:"unit,omitempty"`

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

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

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

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

// Context: `Context` defines which contexts an API
// requests.
//
// Example:
//
//     context:
//       rules:
//       - selector: "*"
//         requested:
//         - google.rpc.context.ProjectContext
//         - google.rpc.context.OriginContext
//
// The above specifies that all methods in the API
// request
// `google.rpc.context.ProjectContext`
// and
// `google.rpc.context.OriginContext`.
//
// Available context types are defined in
// package
// `google.rpc.context`.
//
// This also provides mechanism to whitelist any protobuf message
// extension that
// can be sent in grpc metadata using
// “x-goog-ext-<extension_id>-bin”
// and
// “x-goog-ext-<extension_id>-jspb” format. For example, list any
// service
// specific protobuf types that can appear in grpc metadata as follows
// in your
// yaml file:
//
// Example:
//
//     context:
//       rules:
//        - selector:
// "google.example.library.v1.LibraryService.CreateBook"
//          allowed_request_extensions:
//          - google.foo.v1.NewExtension
//          allowed_response_extensions:
//          - google.foo.v1.NewExtension
//
// You can also specify extension ID instead of fully qualified
// extension name
// here.
type Context struct {
	// Rules: A list of RPC context rules that apply to individual API
	// methods.
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*ContextRule `json:"rules,omitempty"`

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

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

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

// ContextRule: A context rule provides information about the context
// for an individual API
// element.
type ContextRule struct {
	// AllowedRequestExtensions: A list of full type names or extension IDs
	// of extensions allowed in grpc
	// side channel from client to backend.
	AllowedRequestExtensions []string `json:"allowedRequestExtensions,omitempty"`

	// AllowedResponseExtensions: A list of full type names or extension IDs
	// of extensions allowed in grpc
	// side channel from backend to client.
	AllowedResponseExtensions []string `json:"allowedResponseExtensions,omitempty"`

	// Provided: A list of full type names of provided contexts.
	Provided []string `json:"provided,omitempty"`

	// Requested: A list of full type names of requested contexts.
	Requested []string `json:"requested,omitempty"`

	// Selector: Selects the methods to which this rule applies.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

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

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

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

// Control: Selects and configures the service controller used by the
// service.  The
// service controller handles features like abuse, quota, billing,
// logging,
// monitoring, etc.
type Control struct {
	// Environment: The service control environment to use. If empty, no
	// control plane
	// feature (like quota and billing) will be enabled.
	Environment string `json:"environment,omitempty"`

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

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

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

// CustomError: Customize service error responses.  For example, list
// any service
// specific protobuf types that can appear in error detail lists
// of
// error responses.
//
// Example:
//
//     custom_error:
//       types:
//       - google.foo.v1.CustomError
//       - google.foo.v1.AnotherError
type CustomError struct {
	// Rules: The list of custom error rules that apply to individual API
	// messages.
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*CustomErrorRule `json:"rules,omitempty"`

	// Types: The list of custom error detail types, e.g.
	// 'google.foo.v1.CustomError'.
	Types []string `json:"types,omitempty"`

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

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

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

// CustomErrorRule: A custom error rule.
type CustomErrorRule struct {
	// IsErrorType: Mark this message as possible payload in error response.
	//  Otherwise,
	// objects of this type will be filtered when they appear in error
	// payload.
	IsErrorType bool `json:"isErrorType,omitempty"`

	// Selector: Selects messages to which this rule applies.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

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

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

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

// CustomHttpPattern: A custom pattern is used for defining custom HTTP
// verb.
type CustomHttpPattern struct {
	// Kind: The name of this custom HTTP verb.
	Kind string `json:"kind,omitempty"`

	// Path: The path matched by this custom verb.
	Path string `json:"path,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 *CustomHttpPattern) MarshalJSON() ([]byte, error) {
	type NoMethod CustomHttpPattern
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DisableServiceRequest: Request message for the `DisableService`
// method.
type DisableServiceRequest struct {
}

// DisableServiceResponse: Response message for the `DisableService`
// method.
// This response message is assigned to the `response` field of the
// returned
// Operation when that operation is done.
type DisableServiceResponse struct {
	// Service: The new state of the service after disabling.
	Service *GoogleApiServiceusageV1Service `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 *DisableServiceResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DisableServiceResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Documentation: `Documentation` provides the information for
// describing a service.
//
// Example:
// <pre><code>documentation:
//   summary: >
//     The Google Calendar API gives access
//     to most calendar features.
//   pages:
//   - name: Overview
//     content: &#40;== include google/foo/overview.md ==&#41;
//   - name: Tutorial
//     content: &#40;== include google/foo/tutorial.md ==&#41;
//     subpages;
//     - name: Java
//       content: &#40;== include google/foo/tutorial_java.md ==&#41;
//   rules:
//   - selector: google.calendar.Calendar.Get
//     description: >
//       ...
//   - selector: google.calendar.Calendar.Put
//     description: >
//       ...
// </code></pre>
// Documentation is provided in markdown syntax. In addition to
// standard markdown features, definition lists, tables and fenced
// code blocks are supported. Section headers can be provided and
// are
// interpreted relative to the section nesting of the context where
// a documentation fragment is embedded.
//
// Documentation from the IDL is merged with documentation defined
// via the config at normalization time, where documentation provided
// by config rules overrides IDL provided.
//
// A number of constructs specific to the API platform are supported
// in documentation text.
//
// In order to reference a proto element, the following
// notation can be
// used:
// <pre><code>&#91;fully.qualified.proto.name]&#91;]</code></pre>
// T
// o override the display text used for the link, this can be
// used:
// <pre><code>&#91;display
// text]&#91;fully.qualified.proto.name]</code></pre>
// Text can be excluded from doc using the following
// notation:
// <pre><code>&#40;-- internal comment --&#41;</code></pre>
//
// A few directives are available in documentation. Note that
// directives must appear on a single line to be properly
// identified. The `include` directive includes a markdown file from
// an external source:
// <pre><code>&#40;== include path/to/file ==&#41;</code></pre>
// The `resource_for` directive marks a message to be the resource of
// a collection in REST view. If it is not specified, tools attempt
// to infer the resource from the operations in a
// collection:
// <pre><code>&#40;== resource_for v1.shelves.books
// ==&#41;</code></pre>
// The directive `suppress_warning` does not directly affect
// documentation
// and is documented together with service config validation.
type Documentation struct {
	// DocumentationRootUrl: The URL to the root of documentation.
	DocumentationRootUrl string `json:"documentationRootUrl,omitempty"`

	// Overview: Declares a single overview page. For
	// example:
	// <pre><code>documentation:
	//   summary: ...
	//   overview: &#40;== include overview.md ==&#41;
	// </code></pre>
	// This is a shortcut for the following declaration (using pages
	// style):
	// <pre><code>documentation:
	//   summary: ...
	//   pages:
	//   - name: Overview
	//     content: &#40;== include overview.md ==&#41;
	// </code></pre>
	// Note: you cannot specify both `overview` field and `pages` field.
	Overview string `json:"overview,omitempty"`

	// Pages: The top level pages for the documentation set.
	Pages []*Page `json:"pages,omitempty"`

	// Rules: A list of documentation rules that apply to individual API
	// elements.
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*DocumentationRule `json:"rules,omitempty"`

	// ServiceRootUrl: Specifies the service root url if the default one
	// (the service name
	// from the yaml file) is not suitable. This can be seen in any
	// fully
	// specified service urls as well as sections that show a base that
	// other
	// urls are relative to.
	ServiceRootUrl string `json:"serviceRootUrl,omitempty"`

	// Summary: A short summary of what the service does. Can only be
	// provided by
	// plain text.
	Summary string `json:"summary,omitempty"`

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

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

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

// DocumentationRule: A documentation rule provides information about
// individual API elements.
type DocumentationRule struct {
	// DeprecationDescription: Deprecation description of the selected
	// element(s). It can be provided if
	// an element is marked as `deprecated`.
	DeprecationDescription string `json:"deprecationDescription,omitempty"`

	// Description: Description of the selected API(s).
	Description string `json:"description,omitempty"`

	// Selector: The selector is a comma-separated list of patterns. Each
	// pattern is a
	// qualified name of the element which may end in "*", indicating a
	// wildcard.
	// Wildcards are only allowed at the end and for a whole component of
	// the
	// qualified name, i.e. "foo.*" is ok, but not "foo.b*" or "foo.*.bar".
	// A
	// wildcard will match one or more components. To specify a default for
	// all
	// applicable elements, the whole pattern "*" is used.
	Selector string `json:"selector,omitempty"`

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

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

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

// Empty: A generic empty message that you can re-use to avoid defining
// duplicated
// empty messages in your APIs. A typical example is to use it as the
// request
// or the response type of an API method. For instance:
//
//     service Foo {
//       rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty);
//     }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
type Empty struct {
}

// EnableFailure: Provides error messages for the failing services.
type EnableFailure struct {
	// ErrorMessage: An error message describing why the service could not
	// be enabled.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// ServiceId: The service id of a service that could not be enabled.
	ServiceId string `json:"serviceId,omitempty"`

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

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

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

// EnableServiceRequest: Request message for the `EnableService` method.
type EnableServiceRequest struct {
}

// EnableServiceResponse: Response message for the `EnableService`
// method.
// This response message is assigned to the `response` field of the
// returned
// Operation when that operation is done.
type EnableServiceResponse struct {
	// Service: The new state of the service after enabling.
	Service *GoogleApiServiceusageV1Service `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 *EnableServiceResponse) MarshalJSON() ([]byte, error) {
	type NoMethod EnableServiceResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Endpoint: `Endpoint` describes a network endpoint that serves a set
// of APIs.
// A service may expose any number of endpoints, and all endpoints share
// the
// same service configuration, such as quota configuration and
// monitoring
// configuration.
//
// Example service configuration:
//
//     name: library-example.googleapis.com
//     endpoints:
//       # Below entry makes 'google.example.library.v1.Library'
//       # API be served from endpoint address
// library-example.googleapis.com.
//       # It also allows HTTP OPTIONS calls to be passed to the
// backend, for
//       # it to decide whether the subsequent cross-origin request is
//       # allowed to proceed.
//     - name: library-example.googleapis.com
//       allow_cors: true
type Endpoint struct {
	// Aliases: DEPRECATED: This field is no longer supported. Instead of
	// using aliases,
	// please specify multiple google.api.Endpoint for each of the
	// intended
	// aliases.
	//
	// Additional names that this endpoint will be hosted on.
	Aliases []string `json:"aliases,omitempty"`

	// AllowCors:
	// Allowing
	// [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sh
	// aring), aka
	// cross-domain traffic, would allow the backends served from this
	// endpoint to
	// receive and respond to HTTP OPTIONS requests. The response will be
	// used by
	// the browser to determine whether the subsequent cross-origin request
	// is
	// allowed to proceed.
	AllowCors bool `json:"allowCors,omitempty"`

	// Name: The canonical name of this endpoint.
	Name string `json:"name,omitempty"`

	// Target: The specification of an Internet routable address of API
	// frontend that will
	// handle requests to this
	// [API
	// Endpoint](https://cloud.google.com/apis/design/glossary). It should
	// be
	// either a valid IPv4 address or a fully-qualified domain name. For
	// example,
	// "8.8.8.8" or "myservice.appspot.com".
	Target string `json:"target,omitempty"`

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

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

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

// Enum: Enum type definition.
type Enum struct {
	// Enumvalue: Enum value definitions.
	Enumvalue []*EnumValue `json:"enumvalue,omitempty"`

	// Name: Enum type name.
	Name string `json:"name,omitempty"`

	// Options: Protocol buffer options.
	Options []*Option `json:"options,omitempty"`

	// SourceContext: The source context.
	SourceContext *SourceContext `json:"sourceContext,omitempty"`

	// Syntax: The source syntax.
	//
	// Possible values:
	//   "SYNTAX_PROTO2" - Syntax `proto2`.
	//   "SYNTAX_PROTO3" - Syntax `proto3`.
	Syntax string `json:"syntax,omitempty"`

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

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

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

// EnumValue: Enum value definition.
type EnumValue struct {
	// Name: Enum value name.
	Name string `json:"name,omitempty"`

	// Number: Enum value number.
	Number int64 `json:"number,omitempty"`

	// Options: Protocol buffer options.
	Options []*Option `json:"options,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 *EnumValue) MarshalJSON() ([]byte, error) {
	type NoMethod EnumValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Field: A single field of a message type.
type Field struct {
	// Cardinality: The field cardinality.
	//
	// Possible values:
	//   "CARDINALITY_UNKNOWN" - For fields with unknown cardinality.
	//   "CARDINALITY_OPTIONAL" - For optional fields.
	//   "CARDINALITY_REQUIRED" - For required fields. Proto2 syntax only.
	//   "CARDINALITY_REPEATED" - For repeated fields.
	Cardinality string `json:"cardinality,omitempty"`

	// DefaultValue: The string value of the default value of this field.
	// Proto2 syntax only.
	DefaultValue string `json:"defaultValue,omitempty"`

	// JsonName: The field JSON name.
	JsonName string `json:"jsonName,omitempty"`

	// Kind: The field type.
	//
	// Possible values:
	//   "TYPE_UNKNOWN" - Field type unknown.
	//   "TYPE_DOUBLE" - Field type double.
	//   "TYPE_FLOAT" - Field type float.
	//   "TYPE_INT64" - Field type int64.
	//   "TYPE_UINT64" - Field type uint64.
	//   "TYPE_INT32" - Field type int32.
	//   "TYPE_FIXED64" - Field type fixed64.
	//   "TYPE_FIXED32" - Field type fixed32.
	//   "TYPE_BOOL" - Field type bool.
	//   "TYPE_STRING" - Field type string.
	//   "TYPE_GROUP" - Field type group. Proto2 syntax only, and
	// deprecated.
	//   "TYPE_MESSAGE" - Field type message.
	//   "TYPE_BYTES" - Field type bytes.
	//   "TYPE_UINT32" - Field type uint32.
	//   "TYPE_ENUM" - Field type enum.
	//   "TYPE_SFIXED32" - Field type sfixed32.
	//   "TYPE_SFIXED64" - Field type sfixed64.
	//   "TYPE_SINT32" - Field type sint32.
	//   "TYPE_SINT64" - Field type sint64.
	Kind string `json:"kind,omitempty"`

	// Name: The field name.
	Name string `json:"name,omitempty"`

	// Number: The field number.
	Number int64 `json:"number,omitempty"`

	// OneofIndex: The index of the field type in `Type.oneofs`, for message
	// or enumeration
	// types. The first type has index 1; zero means the type is not in the
	// list.
	OneofIndex int64 `json:"oneofIndex,omitempty"`

	// Options: The protocol buffer options.
	Options []*Option `json:"options,omitempty"`

	// Packed: Whether to use alternative packed wire representation.
	Packed bool `json:"packed,omitempty"`

	// TypeUrl: The field type URL, without the scheme, for message or
	// enumeration
	// types. Example: "type.googleapis.com/google.protobuf.Timestamp".
	TypeUrl string `json:"typeUrl,omitempty"`

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

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

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

// GetServiceIdentityResponse: Response message for getting service
// identity.
type GetServiceIdentityResponse struct {
	// Identity: Service identity that service producer can use to access
	// consumer
	// resources. If exists is true, it contains email and unique_id. If
	// exists is
	// false, it contains pre-constructed email and empty unique_id.
	Identity *ServiceIdentity `json:"identity,omitempty"`

	// State: Service identity state.
	//
	// Possible values:
	//   "IDENTITY_STATE_UNSPECIFIED" - Default service identity state. This
	// value is used if the state is
	// omitted.
	//   "ACTIVE" - Service identity has been created and can be used.
	State string `json:"state,omitempty"`

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

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

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

// GoogleApiService: `Service` is the root object of Google service
// configuration schema. It
// describes basic information about a service, such as the name and
// the
// title, and delegates other aspects to sub-sections. Each sub-section
// is
// either a proto message or a repeated proto message that configures
// a
// specific aspect, such as auth. See each proto message definition for
// details.
//
// Example:
//
//     type: google.api.Service
//     config_version: 3
//     name: calendar.googleapis.com
//     title: Google Calendar API
//     apis:
//     - name: google.calendar.v3.Calendar
//     authentication:
//       providers:
//       - id: google_calendar_auth
//         jwks_uri: https://www.googleapis.com/oauth2/v1/certs
//         issuer: https://securetoken.google.com
//       rules:
//       - selector: "*"
//         requirements:
//           provider_id: google_calendar_auth
type GoogleApiService struct {
	// Apis: A list of API interfaces exported by this service. Only the
	// `name` field
	// of the google.protobuf.Api needs to be provided by the
	// configuration
	// author, as the remaining fields will be derived from the IDL during
	// the
	// normalization process. It is an error to specify an API interface
	// here
	// which cannot be resolved against the associated IDL files.
	Apis []*Api `json:"apis,omitempty"`

	// Authentication: Auth configuration.
	Authentication *Authentication `json:"authentication,omitempty"`

	// Backend: API backend configuration.
	Backend *Backend `json:"backend,omitempty"`

	// Billing: Billing configuration.
	Billing *Billing `json:"billing,omitempty"`

	// ConfigVersion: The semantic version of the service configuration. The
	// config version
	// affects the interpretation of the service configuration. For
	// example,
	// certain features are enabled by default for certain config
	// versions.
	//
	// The latest config version is `3`.
	ConfigVersion int64 `json:"configVersion,omitempty"`

	// Context: Context configuration.
	Context *Context `json:"context,omitempty"`

	// Control: Configuration for the service control plane.
	Control *Control `json:"control,omitempty"`

	// CustomError: Custom error configuration.
	CustomError *CustomError `json:"customError,omitempty"`

	// Documentation: Additional API documentation.
	Documentation *Documentation `json:"documentation,omitempty"`

	// Endpoints: Configuration for network endpoints.  If this is empty,
	// then an endpoint
	// with the same name as the service is automatically generated to
	// service all
	// defined APIs.
	Endpoints []*Endpoint `json:"endpoints,omitempty"`

	// Enums: A list of all enum types included in this API service.
	// Enums
	// referenced directly or indirectly by the `apis` are
	// automatically
	// included.  Enums which are not referenced but shall be
	// included
	// should be listed here by name. Example:
	//
	//     enums:
	//     - name: google.someapi.v1.SomeEnum
	Enums []*Enum `json:"enums,omitempty"`

	// Http: HTTP configuration.
	Http *Http `json:"http,omitempty"`

	// Id: A unique ID for a specific instance of this message, typically
	// assigned
	// by the client for tracking purpose. Must be no longer than 63
	// characters
	// and only lower case letters, digits, '.', '_' and '-' are allowed.
	// If
	// empty, the server may choose to generate one instead.
	Id string `json:"id,omitempty"`

	// Logging: Logging configuration.
	Logging *Logging `json:"logging,omitempty"`

	// Logs: Defines the logs used by this service.
	Logs []*LogDescriptor `json:"logs,omitempty"`

	// Metrics: Defines the metrics used by this service.
	Metrics []*MetricDescriptor `json:"metrics,omitempty"`

	// MonitoredResources: Defines the monitored resources used by this
	// service. This is required
	// by the Service.monitoring and Service.logging configurations.
	MonitoredResources []*MonitoredResourceDescriptor `json:"monitoredResources,omitempty"`

	// Monitoring: Monitoring configuration.
	Monitoring *Monitoring `json:"monitoring,omitempty"`

	// Name: The service name, which is a DNS-like logical identifier for
	// the
	// service, such as `calendar.googleapis.com`. The service
	// name
	// typically goes through DNS verification to make sure the owner
	// of the service also owns the DNS name.
	Name string `json:"name,omitempty"`

	// ProducerProjectId: The Google project that owns this service.
	ProducerProjectId string `json:"producerProjectId,omitempty"`

	// Quota: Quota configuration.
	Quota *Quota `json:"quota,omitempty"`

	// SourceInfo: Output only. The source information for this
	// configuration if available.
	SourceInfo *SourceInfo `json:"sourceInfo,omitempty"`

	// SystemParameters: System parameter configuration.
	SystemParameters *SystemParameters `json:"systemParameters,omitempty"`

	// SystemTypes: A list of all proto message types included in this API
	// service.
	// It serves similar purpose as [google.api.Service.types], except
	// that
	// these types are not needed by user-defined APIs. Therefore, they will
	// not
	// show up in the generated discovery doc. This field should only be
	// used
	// to define system APIs in ESF.
	SystemTypes []*Type `json:"systemTypes,omitempty"`

	// Title: The product title for this service.
	Title string `json:"title,omitempty"`

	// Types: A list of all proto message types included in this API
	// service.
	// Types referenced directly or indirectly by the `apis`
	// are
	// automatically included.  Messages which are not referenced but
	// shall be included, such as types used by the `google.protobuf.Any`
	// type,
	// should be listed here by name. Example:
	//
	//     types:
	//     - name: google.protobuf.Int32
	Types []*Type `json:"types,omitempty"`

	// Usage: Configuration controlling usage of this service.
	Usage *Usage `json:"usage,omitempty"`

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

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

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

// GoogleApiServiceIdentity: The per-product per-project service
// identity for a service.
//
//
// Use this field to configure per-product per-project service
// identity.
// Example of a service identity configuration.
//
//     usage:
//       service_identity:
//       - service_account_parent: "projects/123456789"
//         display_name: "Cloud XXX Service Agent"
//         description: "Used as the identity of Cloud XXX to access
// resources"
type GoogleApiServiceIdentity struct {
	// Description: Optional. A user-specified opaque description of the
	// service account.
	// Must be less than or equal to 256 UTF-8 bytes.
	Description string `json:"description,omitempty"`

	// DisplayName: Optional. A user-specified name for the service
	// account.
	// Must be less than or equal to 100 UTF-8 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// ServiceAccountParent: A service account project that hosts the
	// service accounts.
	//
	// An example name would be:
	// `projects/123456789`
	ServiceAccountParent string `json:"serviceAccountParent,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 *GoogleApiServiceIdentity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleApiServiceIdentity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleApiServiceusageV1OperationMetadata: The operation metadata
// returned for the batchend services operation.
type GoogleApiServiceusageV1OperationMetadata struct {
	// ResourceNames: The full name of the resources that this operation is
	// directly
	// associated with.
	ResourceNames []string `json:"resourceNames,omitempty"`

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

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

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

// GoogleApiServiceusageV1Service: A service that is available for use
// by the consumer.
type GoogleApiServiceusageV1Service struct {
	// Config: The service configuration of the available service.
	// Some fields may be filtered out of the configuration in responses
	// to
	// the `ListServices` method. These fields are present only in responses
	// to
	// the `GetService` method.
	Config *GoogleApiServiceusageV1ServiceConfig `json:"config,omitempty"`

	// Name: The resource name of the consumer and service.
	//
	// A valid name would be:
	// - projects/123/services/serviceusage.googleapis.com
	Name string `json:"name,omitempty"`

	// Parent: The resource name of the consumer.
	//
	// A valid name would be:
	// - projects/123
	Parent string `json:"parent,omitempty"`

	// State: Whether or not the service has been enabled for use by the
	// consumer.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - The default value, which indicates that the
	// enabled state of the service
	// is unspecified or not meaningful. Currently, all consumers other
	// than
	// projects (such as folders and organizations) are always in this
	// state.
	//   "DISABLED" - The service cannot be used by this consumer. It has
	// either been explicitly
	// disabled, or has never been enabled.
	//   "ENABLED" - The service has been explicitly enabled for use by this
	// consumer.
	State string `json:"state,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 *GoogleApiServiceusageV1Service) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleApiServiceusageV1Service
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleApiServiceusageV1ServiceConfig: The configuration of the
// service.
type GoogleApiServiceusageV1ServiceConfig struct {
	// Apis: A list of API interfaces exported by this service. Contains
	// only the names,
	// versions, and method names of the interfaces.
	Apis []*Api `json:"apis,omitempty"`

	// Authentication: Auth configuration. Contains only the OAuth rules.
	Authentication *Authentication `json:"authentication,omitempty"`

	// Documentation: Additional API documentation. Contains only the
	// summary and the
	// documentation URL.
	Documentation *Documentation `json:"documentation,omitempty"`

	// Endpoints: Configuration for network endpoints. Contains only the
	// names and aliases
	// of the endpoints.
	Endpoints []*Endpoint `json:"endpoints,omitempty"`

	// Name: The DNS address at which this service is available.
	//
	// An example DNS address would be:
	// `calendar.googleapis.com`.
	Name string `json:"name,omitempty"`

	// Quota: Quota configuration.
	Quota *Quota `json:"quota,omitempty"`

	// Title: The product title for this service.
	Title string `json:"title,omitempty"`

	// Usage: Configuration controlling usage of this service.
	Usage *Usage `json:"usage,omitempty"`

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

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

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

// GoogleApiServiceusageV1beta1GetServiceIdentityResponse: Response
// message for getting service identity.
type GoogleApiServiceusageV1beta1GetServiceIdentityResponse struct {
	// Identity: Service identity that service producer can use to access
	// consumer
	// resources. If exists is true, it contains email and unique_id. If
	// exists is
	// false, it contains pre-constructed email and empty unique_id.
	Identity *GoogleApiServiceusageV1beta1ServiceIdentity `json:"identity,omitempty"`

	// State: Service identity state.
	//
	// Possible values:
	//   "IDENTITY_STATE_UNSPECIFIED" - Default service identity state. This
	// value is used if the state is
	// omitted.
	//   "ACTIVE" - Service identity has been created and can be used.
	State string `json:"state,omitempty"`

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

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

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

// GoogleApiServiceusageV1beta1ServiceIdentity: Service identity for a
// service. This is the identity that service producer
// should use to access consumer resources.
type GoogleApiServiceusageV1beta1ServiceIdentity struct {
	// Email: The email address of the service account that a service
	// producer would use
	// to access consumer resources.
	Email string `json:"email,omitempty"`

	// UniqueId: The unique and stable id of the service
	// account.
	// https://cloud.google.com/iam/reference/rest/v1/projects.servi
	// ceAccounts#ServiceAccount
	UniqueId string `json:"uniqueId,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 *GoogleApiServiceusageV1beta1ServiceIdentity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleApiServiceusageV1beta1ServiceIdentity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Http: Defines the HTTP configuration for an API service. It contains
// a list of
// HttpRule, each specifying the mapping of an RPC method
// to one or more HTTP REST API methods.
type Http struct {
	// FullyDecodeReservedExpansion: When set to true, URL path parameters
	// will be fully URI-decoded except in
	// cases of single segment matches in reserved expansion, where "%2F"
	// will be
	// left encoded.
	//
	// The default behavior is to not decode RFC 6570 reserved characters in
	// multi
	// segment matches.
	FullyDecodeReservedExpansion bool `json:"fullyDecodeReservedExpansion,omitempty"`

	// Rules: A list of HTTP configuration rules that apply to individual
	// API methods.
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*HttpRule `json:"rules,omitempty"`

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

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

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

// HttpRule: # gRPC Transcoding
//
// gRPC Transcoding is a feature for mapping between a gRPC method and
// one or
// more HTTP REST endpoints. It allows developers to build a single API
// service
// that supports both gRPC APIs and REST APIs. Many systems, including
// [Google
// APIs](https://github.com/googleapis/googleapis),
// [Cloud Endpoints](https://cloud.google.com/endpoints),
// [gRPC
// Gateway](https://github.com/grpc-ecosystem/grpc-gateway),
// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this
// feature
// and use it for large scale production services.
//
// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping
// specifies
// how different portions of the gRPC request message are mapped to the
// URL
// path, URL query parameters, and HTTP request body. It also controls
// how the
// gRPC response message is mapped to the HTTP response body. `HttpRule`
// is
// typically specified as an `google.api.http` annotation on the gRPC
// method.
//
// Each mapping specifies a URL path template and an HTTP method. The
// path
// template may refer to one or more fields in the gRPC request message,
// as long
// as each field is a non-repeated field with a primitive (non-message)
// type.
// The path template controls how fields of the request message are
// mapped to
// the URL path.
//
// Example:
//
//     service Messaging {
//       rpc GetMessage(GetMessageRequest) returns (Message) {
//         option (google.api.http) = {
//             get: "/v1/{name=messages/*}"
//         };
//       }
//     }
//     message GetMessageRequest {
//       string name = 1; // Mapped to URL path.
//     }
//     message Message {
//       string text = 1; // The resource content.
//     }
//
// This enables an HTTP REST to gRPC mapping as below:
//
// HTTP | gRPC
// -----|-----
// `GET /v1/messages/123456`  | `GetMessage(name:
// "messages/123456")`
//
// Any fields in the request message which are not bound by the path
// template
// automatically become HTTP query parameters if there is no HTTP
// request body.
// For example:
//
//     service Messaging {
//       rpc GetMessage(GetMessageRequest) returns (Message) {
//         option (google.api.http) = {
//             get:"/v1/messages/{message_id}"
//         };
//       }
//     }
//     message GetMessageRequest {
//       message SubMessage {
//         string subfield = 1;
//       }
//       string message_id = 1; // Mapped to URL path.
//       int64 revision = 2;    // Mapped to URL query parameter
// `revision`.
//       SubMessage sub = 3;    // Mapped to URL query parameter
// `sub.subfield`.
//     }
//
// This enables a HTTP JSON to RPC mapping as below:
//
// HTTP | gRPC
// -----|-----
// `GET /v1/messages/123456?revision=2&sub.subfield=foo`
// |
// `GetMessage(message_id: "123456" revision: 2 sub:
// SubMessage(subfield:
// "foo"))`
//
// Note that fields which are mapped to URL query parameters must have
// a
// primitive type or a repeated primitive type or a non-repeated message
// type.
// In the case of a repeated type, the parameter can be repeated in the
// URL
// as `...?param=A&param=B`. In the case of a message type, each field
// of the
// message is mapped to a separate parameter, such
// as
// `...?foo.a=A&foo.b=B&foo.c=C`.
//
// For HTTP methods that allow a request body, the `body`
// field
// specifies the mapping. Consider a REST update method on the
// message resource collection:
//
//     service Messaging {
//       rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
//         option (google.api.http) = {
//           patch: "/v1/messages/{message_id}"
//           body: "message"
//         };
//       }
//     }
//     message UpdateMessageRequest {
//       string message_id = 1; // mapped to the URL
//       Message message = 2;   // mapped to the body
//     }
//
// The following HTTP JSON to RPC mapping is enabled, where
// the
// representation of the JSON in the request body is determined
// by
// protos JSON encoding:
//
// HTTP | gRPC
// -----|-----
// `PATCH /v1/messages/123456 { "text": "Hi!" }` |
// `UpdateMessage(message_id:
// "123456" message { text: "Hi!" })`
//
// The special name `*` can be used in the body mapping to define
// that
// every field not bound by the path template should be mapped to
// the
// request body.  This enables the following alternative definition
// of
// the update method:
//
//     service Messaging {
//       rpc UpdateMessage(Message) returns (Message) {
//         option (google.api.http) = {
//           patch: "/v1/messages/{message_id}"
//           body: "*"
//         };
//       }
//     }
//     message Message {
//       string message_id = 1;
//       string text = 2;
//     }
//
//
// The following HTTP JSON to RPC mapping is enabled:
//
// HTTP | gRPC
// -----|-----
// `PATCH /v1/messages/123456 { "text": "Hi!" }` |
// `UpdateMessage(message_id:
// "123456" text: "Hi!")`
//
// Note that when using `*` in the body mapping, it is not possible
// to
// have HTTP parameters, as all fields not bound by the path end in
// the body. This makes this option more rarely used in practice
// when
// defining REST APIs. The common usage of `*` is in custom
// methods
// which don't use the URL at all for transferring data.
//
// It is possible to define multiple HTTP methods for one RPC by
// using
// the `additional_bindings` option. Example:
//
//     service Messaging {
//       rpc GetMessage(GetMessageRequest) returns (Message) {
//         option (google.api.http) = {
//           get: "/v1/messages/{message_id}"
//           additional_bindings {
//             get: "/v1/users/{user_id}/messages/{message_id}"
//           }
//         };
//       }
//     }
//     message GetMessageRequest {
//       string message_id = 1;
//       string user_id = 2;
//     }
//
// This enables the following two alternative HTTP JSON to RPC
// mappings:
//
// HTTP | gRPC
// -----|-----
// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")`
// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me"
// message_id:
// "123456")`
//
// ## Rules for HTTP mapping
//
// 1. Leaf request fields (recursive expansion nested messages in the
// request
//    message) are classified into three categories:
//    - Fields referred by the path template. They are passed via the
// URL path.
//    - Fields referred by the HttpRule.body. They are passed via the
// HTTP
//      request body.
//    - All other fields are passed via the URL query parameters, and
// the
//      parameter name is the field path in the request message. A
// repeated
//      field can be represented as multiple query parameters under the
// same
//      name.
//  2. If HttpRule.body is "*", there is no URL query parameter, all
// fields
//     are passed via URL path and HTTP request body.
//  3. If HttpRule.body is omitted, there is no HTTP request body, all
//     fields are passed via URL path and URL query parameters.
//
// ### Path template syntax
//
//     Template = "/" Segments [ Verb ] ;
//     Segments = Segment { "/" Segment } ;
//     Segment  = "*" | "**" | LITERAL | Variable ;
//     Variable = "{" FieldPath [ "=" Segments ] "}" ;
//     FieldPath = IDENT { "." IDENT } ;
//     Verb     = ":" LITERAL ;
//
// The syntax `*` matches a single URL path segment. The syntax `**`
// matches
// zero or more URL path segments, which must be the last part of the
// URL path
// except the `Verb`.
//
// The syntax `Variable` matches part of the URL path as specified by
// its
// template. A variable template must not contain other variables. If a
// variable
// matches a single path segment, its template may be omitted, e.g.
// `{var}`
// is equivalent to `{var=*}`.
//
// The syntax `LITERAL` matches literal text in the URL path. If the
// `LITERAL`
// contains any reserved character, such characters should be
// percent-encoded
// before the matching.
//
// If a variable contains exactly one path segment, such as "{var}"
// or
// "{var=*}", when such a variable is expanded into a URL path on the
// client
// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded.
// The
// server side does the reverse decoding. Such variables show up in
// the
// [Discovery
// Document](https://developers.google.com/discovery/v1/re
// ference/apis) as
// `{var}`.
//
// If a variable contains multiple path segments, such as
// "{var=foo/*}"
// or "{var=**}", when such a variable is expanded into a URL path on
// the
// client side, all characters except `[-_.~/0-9a-zA-Z]` are
// percent-encoded.
// The server side does the reverse decoding, except "%2F" and "%2f" are
// left
// unchanged. Such variables show up in
// the
// [Discovery
// Document](https://developers.google.com/discovery/v1/re
// ference/apis) as
// `{+var}`.
//
// ## Using gRPC API Service Configuration
//
// gRPC API Service Configuration (service config) is a configuration
// language
// for configuring a gRPC service to become a user-facing product.
// The
// service config is simply the YAML representation of the
// `google.api.Service`
// proto message.
//
// As an alternative to annotating your proto file, you can configure
// gRPC
// transcoding in your service config YAML files. You do this by
// specifying a
// `HttpRule` that maps the gRPC method to a REST endpoint, achieving
// the same
// effect as the proto annotation. This can be particularly useful if
// you
// have a proto that is reused in multiple services. Note that any
// transcoding
// specified in the service config will override any matching
// transcoding
// configuration in the proto.
//
// Example:
//
//     http:
//       rules:
//         # Selects a gRPC method and applies HttpRule to it.
//         - selector: example.v1.Messaging.GetMessage
//           get: /v1/messages/{message_id}/{sub.subfield}
//
// ## Special notes
//
// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints,
// the
// proto to JSON conversion must follow the
// [proto3
// specification](https://developers.google.com/protocol-buffers/
// docs/proto3#json).
//
// While the single segment variable follows the semantics of
// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple
// String
// Expansion, the multi segment variable **does not** follow RFC 6570
// Section
// 3.2.3 Reserved Expansion. The reason is that the Reserved
// Expansion
// does not expand special characters like `?` and `#`, which would
// lead
// to invalid URLs. As the result, gRPC Transcoding uses a custom
// encoding
// for multi segment variables.
//
// The path variables **must not** refer to any repeated or mapped
// field,
// because client libraries are not capable of handling such variable
// expansion.
//
// The path variables **must not** capture the leading "/" character.
// The reason
// is that the most common use case "{var}" does not capture the leading
// "/"
// character. For consistency, all path variables must share the same
// behavior.
//
// Repeated message fields must not be mapped to URL query parameters,
// because
// no client library can support such complicated mapping.
//
// If an API needs to use a JSON array for request or response body, it
// can map
// the request or response body to a repeated field. However, some
// gRPC
// Transcoding implementations may not support this feature.
type HttpRule struct {
	// AdditionalBindings: Additional HTTP bindings for the selector. Nested
	// bindings must
	// not contain an `additional_bindings` field themselves (that is,
	// the nesting may only be one level deep).
	AdditionalBindings []*HttpRule `json:"additionalBindings,omitempty"`

	// AllowHalfDuplex: When this flag is set to true, HTTP requests will be
	// allowed to invoke a
	// half-duplex streaming method.
	AllowHalfDuplex bool `json:"allowHalfDuplex,omitempty"`

	// Body: The name of the request field whose value is mapped to the HTTP
	// request
	// body, or `*` for mapping all request fields not captured by the
	// path
	// pattern to the HTTP body, or omitted for not having any HTTP request
	// body.
	//
	// NOTE: the referred field must be present at the top-level of the
	// request
	// message type.
	Body string `json:"body,omitempty"`

	// Custom: The custom pattern is used for specifying an HTTP method that
	// is not
	// included in the `pattern` field, such as HEAD, or "*" to leave
	// the
	// HTTP method unspecified for this rule. The wild-card rule is
	// useful
	// for services that provide content to Web (HTML) clients.
	Custom *CustomHttpPattern `json:"custom,omitempty"`

	// Delete: Maps to HTTP DELETE. Used for deleting a resource.
	Delete string `json:"delete,omitempty"`

	// Get: Maps to HTTP GET. Used for listing and getting information
	// about
	// resources.
	Get string `json:"get,omitempty"`

	// Patch: Maps to HTTP PATCH. Used for updating a resource.
	Patch string `json:"patch,omitempty"`

	// Post: Maps to HTTP POST. Used for creating a resource or performing
	// an action.
	Post string `json:"post,omitempty"`

	// Put: Maps to HTTP PUT. Used for replacing a resource.
	Put string `json:"put,omitempty"`

	// ResponseBody: Optional. The name of the response field whose value is
	// mapped to the HTTP
	// response body. When omitted, the entire response message will be
	// used
	// as the HTTP response body.
	//
	// NOTE: The referred field must be present at the top-level of the
	// response
	// message type.
	ResponseBody string `json:"responseBody,omitempty"`

	// Selector: Selects a method to which this rule applies.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

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

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

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

// ImportAdminOverridesResponse: Response message for
// ImportAdminOverrides
type ImportAdminOverridesResponse struct {
	// Overrides: The overrides that were created from the imported data.
	Overrides []*QuotaOverride `json:"overrides,omitempty"`

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

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

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

// ImportAdminQuotaPoliciesResponse: Response message for
// ImportAdminQuotaPolicies
type ImportAdminQuotaPoliciesResponse struct {
	// Policies: The policies that were created from the imported data.
	Policies []*AdminQuotaPolicy `json:"policies,omitempty"`

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

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

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

// ImportConsumerOverridesRequest: Request message for
// ImportConsumerOverrides
type ImportConsumerOverridesRequest struct {
	// Force: Whether to force the creation of the quota overrides.
	// If creating an override would cause the effective quota for the
	// consumer to
	// decrease by more than 10 percent, the call is rejected, as a safety
	// measure
	// to avoid accidentally decreasing quota too quickly. Setting the
	// force
	// parameter to true ignores this restriction.
	Force bool `json:"force,omitempty"`

	// InlineSource: The import data is specified in the request message
	// itself
	InlineSource *OverrideInlineSource `json:"inlineSource,omitempty"`

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

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

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

// ImportConsumerOverridesResponse: Response message for
// ImportConsumerOverrides
type ImportConsumerOverridesResponse struct {
	// Overrides: The overrides that were created from the imported data.
	Overrides []*QuotaOverride `json:"overrides,omitempty"`

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

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

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

// JwtLocation: Specifies a location to extract JWT from an API request.
type JwtLocation struct {
	// Header: Specifies HTTP header name to extract JWT token.
	Header string `json:"header,omitempty"`

	// Query: Specifies URL query parameter name to extract JWT token.
	Query string `json:"query,omitempty"`

	// ValuePrefix: The value prefix. The value format is
	// "value_prefix{token}"
	// Only applies to "in" header type. Must be empty for "in" query
	// type.
	// If not empty, the header value has to match (case sensitive) this
	// prefix.
	// If not matched, JWT will not be extracted. If matched, JWT will
	// be
	// extracted after the prefix is removed.
	//
	// For example, for "Authorization: Bearer {JWT}",
	// value_prefix="Bearer " with a space at the end.
	ValuePrefix string `json:"valuePrefix,omitempty"`

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

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

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

// LabelDescriptor: A description of a label.
type LabelDescriptor struct {
	// Description: A human-readable description for the label.
	Description string `json:"description,omitempty"`

	// Key: The label key.
	Key string `json:"key,omitempty"`

	// ValueType: The type of data that can be assigned to the label.
	//
	// Possible values:
	//   "STRING" - A variable-length string. This is the default.
	//   "BOOL" - Boolean; true or false.
	//   "INT64" - A 64-bit signed integer.
	ValueType string `json:"valueType,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 *LabelDescriptor) MarshalJSON() ([]byte, error) {
	type NoMethod LabelDescriptor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListAdminOverridesResponse: Response message for ListAdminOverrides.
type ListAdminOverridesResponse struct {
	// NextPageToken: Token identifying which result to start with; returned
	// by a previous list
	// call.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Overrides: Admin overrides on this limit.
	Overrides []*QuotaOverride `json:"overrides,omitempty"`

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

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

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

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

// ListConsumerOverridesResponse: Response message for
// ListConsumerOverrides.
type ListConsumerOverridesResponse struct {
	// NextPageToken: Token identifying which result to start with; returned
	// by a previous list
	// call.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Overrides: Consumer overrides on this limit.
	Overrides []*QuotaOverride `json:"overrides,omitempty"`

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

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

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

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

// ListConsumerQuotaMetricsResponse: Response message for
// ListConsumerQuotaMetrics
type ListConsumerQuotaMetricsResponse struct {
	// Metrics: Quota settings for the consumer, organized by quota metric.
	Metrics []*ConsumerQuotaMetric `json:"metrics,omitempty"`

	// NextPageToken: Token identifying which result to start with; returned
	// by a previous list
	// call.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// ListOperationsResponse: The response message for
// Operations.ListOperations.
type ListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Operations: A list of operations that matches the specified filter in
	// the request.
	Operations []*Operation `json:"operations,omitempty"`

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

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

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

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

// ListServicesResponse: Response message for the `ListServices` method.
type ListServicesResponse struct {
	// NextPageToken: Token that can be passed to `ListServices` to resume a
	// paginated
	// query.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Services: The available services for the requested project.
	Services []*Service `json:"services,omitempty"`

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

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

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

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

// LogDescriptor: A description of a log type. Example in YAML format:
//
//     - name: library.googleapis.com/activity_history
//       description: The history of borrowing and returning library
// items.
//       display_name: Activity
//       labels:
//       - key: /customer_id
//         description: Identifier of a library customer
type LogDescriptor struct {
	// Description: A human-readable description of this log. This
	// information appears in
	// the documentation and can contain details.
	Description string `json:"description,omitempty"`

	// DisplayName: The human-readable name for this log. This information
	// appears on
	// the user interface and should be concise.
	DisplayName string `json:"displayName,omitempty"`

	// Labels: The set of labels that are available to describe a specific
	// log entry.
	// Runtime requests that contain labels not specified here
	// are
	// considered invalid.
	Labels []*LabelDescriptor `json:"labels,omitempty"`

	// Name: The name of the log. It must be less than 512 characters long
	// and can
	// include the following characters: upper- and lower-case
	// alphanumeric
	// characters [A-Za-z0-9], and punctuation characters including
	// slash, underscore, hyphen, period [/_-.].
	Name string `json:"name,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 *LogDescriptor) MarshalJSON() ([]byte, error) {
	type NoMethod LogDescriptor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Logging: Logging configuration of the service.
//
// The following example shows how to configure logs to be sent to
// the
// producer and consumer projects. In the example, the
// `activity_history`
// log is sent to both the producer and consumer projects, whereas
// the
// `purchase_history` log is only sent to the producer project.
//
//     monitored_resources:
//     - type: library.googleapis.com/branch
//       labels:
//       - key: /city
//         description: The city where the library branch is located
// in.
//       - key: /name
//         description: The name of the branch.
//     logs:
//     - name: activity_history
//       labels:
//       - key: /customer_id
//     - name: purchase_history
//     logging:
//       producer_destinations:
//       - monitored_resource: library.googleapis.com/branch
//         logs:
//         - activity_history
//         - purchase_history
//       consumer_destinations:
//       - monitored_resource: library.googleapis.com/branch
//         logs:
//         - activity_history
type Logging struct {
	// ConsumerDestinations: Logging configurations for sending logs to the
	// consumer project.
	// There can be multiple consumer destinations, each one must have
	// a
	// different monitored resource type. A log can be used in at most
	// one consumer destination.
	ConsumerDestinations []*LoggingDestination `json:"consumerDestinations,omitempty"`

	// ProducerDestinations: Logging configurations for sending logs to the
	// producer project.
	// There can be multiple producer destinations, each one must have
	// a
	// different monitored resource type. A log can be used in at most
	// one producer destination.
	ProducerDestinations []*LoggingDestination `json:"producerDestinations,omitempty"`

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

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

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

// LoggingDestination: Configuration of a specific logging destination
// (the producer project
// or the consumer project).
type LoggingDestination struct {
	// Logs: Names of the logs to be sent to this destination. Each name
	// must
	// be defined in the Service.logs section. If the log name is
	// not a domain scoped name, it will be automatically prefixed with
	// the service name followed by "/".
	Logs []string `json:"logs,omitempty"`

	// MonitoredResource: The monitored resource type. The type must be
	// defined in the
	// Service.monitored_resources section.
	MonitoredResource string `json:"monitoredResource,omitempty"`

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

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

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

// Method: Method represents a method of an API interface.
type Method struct {
	// Name: The simple name of this method.
	Name string `json:"name,omitempty"`

	// Options: Any metadata attached to the method.
	Options []*Option `json:"options,omitempty"`

	// RequestStreaming: If true, the request is streamed.
	RequestStreaming bool `json:"requestStreaming,omitempty"`

	// RequestTypeUrl: A URL of the input message type.
	RequestTypeUrl string `json:"requestTypeUrl,omitempty"`

	// ResponseStreaming: If true, the response is streamed.
	ResponseStreaming bool `json:"responseStreaming,omitempty"`

	// ResponseTypeUrl: The URL of the output message type.
	ResponseTypeUrl string `json:"responseTypeUrl,omitempty"`

	// Syntax: The source syntax of this method.
	//
	// Possible values:
	//   "SYNTAX_PROTO2" - Syntax `proto2`.
	//   "SYNTAX_PROTO3" - Syntax `proto3`.
	Syntax string `json:"syntax,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 *Method) MarshalJSON() ([]byte, error) {
	type NoMethod Method
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MetricDescriptor: Defines a metric type and its schema. Once a metric
// descriptor is created,
// deleting or altering it stops data collection and makes the metric
// type's
// existing data unusable.
//
// The following are specific rules for service defined Monitoring
// metric
// descriptors:
//
// * `type`, `metric_kind`, `value_type` and `description`
//   fields are all required. The `unit` field must be specified
//   if the `value_type` is any of DOUBLE, INT64, DISTRIBUTION.
// * Maximum of default 500 metric descriptors per service is allowed.
// * Maximum of default 10 labels per metric descriptor is allowed.
//
// The default maximum limit can be overridden. Please
// follow
// https://cloud.google.com/monitoring/quotas
type MetricDescriptor struct {
	// Description: A detailed description of the metric, which can be used
	// in documentation.
	Description string `json:"description,omitempty"`

	// DisplayName: A concise name for the metric, which can be displayed in
	// user interfaces.
	// Use sentence case without an ending period, for example "Request
	// count".
	// This field is optional but it is recommended to be set for any
	// metrics
	// associated with user-visible concepts, such as Quota.
	DisplayName string `json:"displayName,omitempty"`

	// Labels: The set of labels that can be used to describe a
	// specific
	// instance of this metric type.
	//
	// The label key name must follow:
	//
	// * Only upper and lower-case letters, digits and underscores (_) are
	//   allowed.
	// * Label name must start with a letter or digit.
	// * The maximum length of a label name is 100 characters.
	//
	// For example,
	// the
	// `appengine.googleapis.com/http/server/response_latencies` metric
	// type has a label for the HTTP response code, `response_code`, so
	// you can look at latencies for successful responses or just
	// for responses that failed.
	Labels []*LabelDescriptor `json:"labels,omitempty"`

	// LaunchStage: Optional. The launch stage of the metric definition.
	//
	// Possible values:
	//   "LAUNCH_STAGE_UNSPECIFIED" - Do not use this default value.
	//   "UNIMPLEMENTED" - The feature is not yet implemented. Users can not
	// use it.
	//   "PRELAUNCH" - Prelaunch features are hidden from users and are only
	// visible internally.
	//   "EARLY_ACCESS" - Early Access features are limited to a closed
	// group of testers. To use
	// these features, you must sign up in advance and sign a Trusted
	// Tester
	// agreement (which includes confidentiality provisions). These features
	// may
	// be unstable, changed in backward-incompatible ways, and are
	// not
	// guaranteed to be released.
	//   "ALPHA" - Alpha is a limited availability test for releases before
	// they are cleared
	// for widespread use. By Alpha, all significant design issues are
	// resolved
	// and we are in the process of verifying functionality. Alpha
	// customers
	// need to apply for access, agree to applicable terms, and have
	// their
	// projects whitelisted. Alpha releases don’t have to be feature
	// complete,
	// no SLAs are provided, and there are no technical support obligations,
	// but
	// they will be far enough along that customers can actually use them
	// in
	// test environments or for limited-use tests -- just like they would
	// in
	// normal production cases.
	//   "BETA" - Beta is the point at which we are ready to open a release
	// for any
	// customer to use. There are no SLA or technical support obligations in
	// a
	// Beta release. Products will be complete from a feature perspective,
	// but
	// may have some open outstanding issues. Beta releases are suitable
	// for
	// limited production use cases.
	//   "GA" - GA features are open to all developers and are considered
	// stable and
	// fully qualified for production use.
	//   "DEPRECATED" - Deprecated features are scheduled to be shut down
	// and removed. For more
	// information, see the “Deprecation Policy” section of our [Terms
	// of
	// Service](https://cloud.google.com/terms/)
	// and the [Google Cloud Platform Subject to the
	// Deprecation
	// Policy](https://cloud.google.com/terms/deprecation) documentation.
	LaunchStage string `json:"launchStage,omitempty"`

	// Metadata: Optional. Metadata which can be used to guide usage of the
	// metric.
	Metadata *MetricDescriptorMetadata `json:"metadata,omitempty"`

	// MetricKind: Whether the metric records instantaneous values, changes
	// to a value, etc.
	// Some combinations of `metric_kind` and `value_type` might not be
	// supported.
	//
	// Possible values:
	//   "METRIC_KIND_UNSPECIFIED" - Do not use this default value.
	//   "GAUGE" - An instantaneous measurement of a value.
	//   "DELTA" - The change in a value during a time interval.
	//   "CUMULATIVE" - A value accumulated over a time interval.
	// Cumulative
	// measurements in a time series should have the same start time
	// and increasing end times, until an event resets the cumulative
	// value to zero and sets a new start time for the following
	// points.
	MetricKind string `json:"metricKind,omitempty"`

	// MonitoredResourceTypes: Read-only. If present, then a time
	// series, which is identified partially by
	// a metric type and a MonitoredResourceDescriptor, that is
	// associated
	// with this metric type can only be associated with one of the
	// monitored
	// resource types listed here.
	MonitoredResourceTypes []string `json:"monitoredResourceTypes,omitempty"`

	// Name: The resource name of the metric descriptor.
	Name string `json:"name,omitempty"`

	// Type: The metric type, including its DNS name prefix. The type is
	// not
	// URL-encoded.
	//
	// All service defined metrics must be prefixed with the service name,
	// in the
	// format of `{service name}/{relative metric name}`, such
	// as
	// `cloudsql.googleapis.com/database/cpu/utilization`. The relative
	// metric
	// name must follow:
	//
	// * Only upper and lower-case letters, digits, '/' and underscores '_'
	// are
	//   allowed.
	// * The maximum number of characters allowed for the
	// relative_metric_name is
	//   100.
	//
	// All user-defined metric types have the DNS
	// name
	// `custom.googleapis.com`, `external.googleapis.com`,
	// or
	// `logging.googleapis.com/user/`.
	//
	// Metric types should use a natural hierarchical grouping. For
	// example:
	//
	//     "custom.googleapis.com/invoice/paid/amount"
	//     "external.googleapis.com/prometheus/up"
	//     "appengine.googleapis.com/http/server/response_latencies"
	Type string `json:"type,omitempty"`

	// Unit: The units in which the metric value is reported. It is only
	// applicable
	// if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The
	// `unit`
	// defines the representation of the stored metric values.
	//
	// Different systems may scale the values to be more easily displayed
	// (so a
	// value of `0.02KBy` _might_ be displayed as `20By`, and a value
	// of
	// `3523KBy` _might_ be displayed as `3.5MBy`). However, if the `unit`
	// is
	// `KBy`, then the value of the metric is always in thousands of bytes,
	// no
	// matter how it may be displayed..
	//
	// If you want a custom metric to record the exact number of CPU-seconds
	// used
	// by a job, you can create an `INT64 CUMULATIVE` metric whose `unit`
	// is
	// `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses
	// 12,005
	// CPU-seconds, then the value is written as `12005`.
	//
	// Alternatively, if you want a custom metric to record data in a
	// more
	// granular way, you can create a `DOUBLE CUMULATIVE` metric whose
	// `unit` is
	// `ks{CPU}`, and then write the value `12.005` (which is
	// `12005/1000`),
	// or use `Kis{CPU}` and write `11.723` (which is `12005/1024`).
	//
	// The supported units are a subset of [The Unified Code for Units
	// of
	// Measure](http://unitsofmeasure.org/ucum.html) standard:
	//
	// **Basic units (UNIT)**
	//
	// * `bit`   bit
	// * `By`    byte
	// * `s`     second
	// * `min`   minute
	// * `h`     hour
	// * `d`     day
	// * `1`     dimensionless
	//
	// **Prefixes (PREFIX)**
	//
	// * `k`     kilo    (10^3)
	// * `M`     mega    (10^6)
	// * `G`     giga    (10^9)
	// * `T`     tera    (10^12)
	// * `P`     peta    (10^15)
	// * `E`     exa     (10^18)
	// * `Z`     zetta   (10^21)
	// * `Y`     yotta   (10^24)
	//
	// * `m`     milli   (10^-3)
	// * `u`     micro   (10^-6)
	// * `n`     nano    (10^-9)
	// * `p`     pico    (10^-12)
	// * `f`     femto   (10^-15)
	// * `a`     atto    (10^-18)
	// * `z`     zepto   (10^-21)
	// * `y`     yocto   (10^-24)
	//
	// * `Ki`    kibi    (2^10)
	// * `Mi`    mebi    (2^20)
	// * `Gi`    gibi    (2^30)
	// * `Ti`    tebi    (2^40)
	// * `Pi`    pebi    (2^50)
	//
	// **Grammar**
	//
	// The grammar also includes these connectors:
	//
	// * `/`    division or ratio (as an infix operator). For examples,
	//          `kBy/{email}` or `MiBy/10ms` (although you should almost
	// never
	//          have `/s` in a metric `unit`; rates should always be
	// computed at
	//          query time from the underlying cumulative or delta value).
	// * `.`    multiplication or composition (as an infix operator). For
	//          examples, `GBy.d` or `k{watt}.h`.
	//
	// The grammar for a unit is as follows:
	//
	//     Expression = Component { "." Component } { "/" Component } ;
	//
	//     Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ]
	//               | Annotation
	//               | "1"
	//               ;
	//
	//     Annotation = "{" NAME "}" ;
	//
	// Notes:
	//
	// * `Annotation` is just a comment if it follows a `UNIT`. If the
	// annotation
	//    is used alone, then the unit is equivalent to `1`. For examples,
	//    `{request}/s == 1/s`, `By{transmitted}/s == By/s`.
	// * `NAME` is a sequence of non-blank printable ASCII characters not
	//    containing `{` or `}`.
	// * `1` represents a unitary [dimensionless
	//    unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1,
	// such
	//    as in `1/s`. It is typically used when none of the basic units
	// are
	//    appropriate. For example, "new users per day" can be represented
	// as
	//    `1/d` or `{new-users}/d` (and a metric value `5` would mean "5
	// new
	//    users). Alternatively, "thousands of page views per day" would be
	//    represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a
	// metric
	//    value of `5.3` would mean "5300 page views per day").
	// * `%` represents dimensionless value of 1/100, and annotates values
	// giving
	//    a percentage (so the metric values are typically in the range of
	// 0..100,
	//    and a metric value `3` means "3 percent").
	// * `10^2.%` indicates a metric contains a ratio, typically in the
	// range
	//    0..1, that will be multiplied by 100 and displayed as a
	// percentage
	//    (so a metric value `0.03` means "3 percent").
	Unit string `json:"unit,omitempty"`

	// ValueType: Whether the measurement is an integer, a floating-point
	// number, etc.
	// Some combinations of `metric_kind` and `value_type` might not be
	// supported.
	//
	// Possible values:
	//   "VALUE_TYPE_UNSPECIFIED" - Do not use this default value.
	//   "BOOL" - The value is a boolean.
	// This value type can be used only if the metric kind is `GAUGE`.
	//   "INT64" - The value is a signed 64-bit integer.
	//   "DOUBLE" - The value is a double precision floating point number.
	//   "STRING" - The value is a text string.
	// This value type can be used only if the metric kind is `GAUGE`.
	//   "DISTRIBUTION" - The value is a `Distribution`.
	//   "MONEY" - The value is money.
	ValueType string `json:"valueType,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 *MetricDescriptor) MarshalJSON() ([]byte, error) {
	type NoMethod MetricDescriptor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MetricDescriptorMetadata: Additional annotations that can be used to
// guide the usage of a metric.
type MetricDescriptorMetadata struct {
	// IngestDelay: The delay of data points caused by ingestion. Data
	// points older than this
	// age are guaranteed to be ingested and available to be read,
	// excluding
	// data loss due to errors.
	IngestDelay string `json:"ingestDelay,omitempty"`

	// LaunchStage: Deprecated. Must use the MetricDescriptor.launch_stage
	// instead.
	//
	// Possible values:
	//   "LAUNCH_STAGE_UNSPECIFIED" - Do not use this default value.
	//   "UNIMPLEMENTED" - The feature is not yet implemented. Users can not
	// use it.
	//   "PRELAUNCH" - Prelaunch features are hidden from users and are only
	// visible internally.
	//   "EARLY_ACCESS" - Early Access features are limited to a closed
	// group of testers. To use
	// these features, you must sign up in advance and sign a Trusted
	// Tester
	// agreement (which includes confidentiality provisions). These features
	// may
	// be unstable, changed in backward-incompatible ways, and are
	// not
	// guaranteed to be released.
	//   "ALPHA" - Alpha is a limited availability test for releases before
	// they are cleared
	// for widespread use. By Alpha, all significant design issues are
	// resolved
	// and we are in the process of verifying functionality. Alpha
	// customers
	// need to apply for access, agree to applicable terms, and have
	// their
	// projects whitelisted. Alpha releases don’t have to be feature
	// complete,
	// no SLAs are provided, and there are no technical support obligations,
	// but
	// they will be far enough along that customers can actually use them
	// in
	// test environments or for limited-use tests -- just like they would
	// in
	// normal production cases.
	//   "BETA" - Beta is the point at which we are ready to open a release
	// for any
	// customer to use. There are no SLA or technical support obligations in
	// a
	// Beta release. Products will be complete from a feature perspective,
	// but
	// may have some open outstanding issues. Beta releases are suitable
	// for
	// limited production use cases.
	//   "GA" - GA features are open to all developers and are considered
	// stable and
	// fully qualified for production use.
	//   "DEPRECATED" - Deprecated features are scheduled to be shut down
	// and removed. For more
	// information, see the “Deprecation Policy” section of our [Terms
	// of
	// Service](https://cloud.google.com/terms/)
	// and the [Google Cloud Platform Subject to the
	// Deprecation
	// Policy](https://cloud.google.com/terms/deprecation) documentation.
	LaunchStage string `json:"launchStage,omitempty"`

	// SamplePeriod: The sampling period of metric data points. For metrics
	// which are written
	// periodically, consecutive data points are stored at this time
	// interval,
	// excluding data loss due to errors. Metrics with a higher granularity
	// have
	// a smaller sampling period.
	SamplePeriod string `json:"samplePeriod,omitempty"`

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

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

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

// MetricRule: Bind API methods to metrics. Binding a method to a metric
// causes that
// metric's configured quota behaviors to apply to the method call.
type MetricRule struct {
	// MetricCosts: Metrics to update when the selected methods are called,
	// and the associated
	// cost applied to each metric.
	//
	// The key of the map is the metric name, and the values are the
	// amount
	// increased for the metric against which the quota limits are
	// defined.
	// The value must not be negative.
	MetricCosts map[string]string `json:"metricCosts,omitempty"`

	// Selector: Selects the methods to which this rule applies.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

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

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

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

// Mixin: Declares an API Interface to be included in this interface.
// The including
// interface must redeclare all the methods from the included interface,
// but
// documentation and options are inherited as follows:
//
// - If after comment and whitespace stripping, the documentation
//   string of the redeclared method is empty, it will be inherited
//   from the original method.
//
// - Each annotation belonging to the service config (http,
//   visibility) which is not set in the redeclared method will be
//   inherited.
//
// - If an http annotation is inherited, the path pattern will be
//   modified as follows. Any version prefix will be replaced by the
//   version of the including interface plus the root path if
//   specified.
//
// Example of a simple mixin:
//
//     package google.acl.v1;
//     service AccessControl {
//       // Get the underlying ACL object.
//       rpc GetAcl(GetAclRequest) returns (Acl) {
//         option (google.api.http).get = "/v1/{resource=**}:getAcl";
//       }
//     }
//
//     package google.storage.v2;
//     service Storage {
//       //       rpc GetAcl(GetAclRequest) returns (Acl);
//
//       // Get a data record.
//       rpc GetData(GetDataRequest) returns (Data) {
//         option (google.api.http).get = "/v2/{resource=**}";
//       }
//     }
//
// Example of a mixin configuration:
//
//     apis:
//     - name: google.storage.v2.Storage
//       mixins:
//       - name: google.acl.v1.AccessControl
//
// The mixin construct implies that all methods in `AccessControl`
// are
// also declared with same name and request/response types in
// `Storage`. A documentation generator or annotation processor will
// see the effective `Storage.GetAcl` method after
// inherting
// documentation and annotations as follows:
//
//     service Storage {
//       // Get the underlying ACL object.
//       rpc GetAcl(GetAclRequest) returns (Acl) {
//         option (google.api.http).get = "/v2/{resource=**}:getAcl";
//       }
//       ...
//     }
//
// Note how the version in the path pattern changed from `v1` to
// `v2`.
//
// If the `root` field in the mixin is specified, it should be
// a
// relative path under which inherited HTTP paths are placed. Example:
//
//     apis:
//     - name: google.storage.v2.Storage
//       mixins:
//       - name: google.acl.v1.AccessControl
//         root: acls
//
// This implies the following inherited HTTP annotation:
//
//     service Storage {
//       // Get the underlying ACL object.
//       rpc GetAcl(GetAclRequest) returns (Acl) {
//         option (google.api.http).get =
// "/v2/acls/{resource=**}:getAcl";
//       }
//       ...
//     }
type Mixin struct {
	// Name: The fully qualified name of the interface which is included.
	Name string `json:"name,omitempty"`

	// Root: If non-empty specifies a path under which inherited HTTP
	// paths
	// are rooted.
	Root string `json:"root,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 *Mixin) MarshalJSON() ([]byte, error) {
	type NoMethod Mixin
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MonitoredResourceDescriptor: An object that describes the schema of a
// MonitoredResource object using a
// type name and a set of labels.  For example, the monitored
// resource
// descriptor for Google Compute Engine VM instances has a type
// of
// "gce_instance" and specifies the use of the labels "instance_id"
// and
// "zone" to identify particular VM instances.
//
// Different services can support different monitored resource
// types.
//
// The following are specific rules to service defined monitored
// resources for
// Monitoring and Logging:
//
// * The `type`, `display_name`, `description`, `labels` and
// `launch_stage`
//   fields are all required.
// * The first label of the monitored resource descriptor must be
//   `resource_container`. There are legacy monitored resource
// descritptors
//   start with `project_id`.
// * It must include a `location` label.
// * Maximum of default 5 service defined monitored resource
// descriptors
//   is allowed per service.
// * Maximum of default 10 labels per monitored resource is
// allowed.
//
// The default maximum limit can be overridden. Please
// follow
// https://cloud.google.com/monitoring/quotas
//
type MonitoredResourceDescriptor struct {
	// Description: Optional. A detailed description of the monitored
	// resource type that might
	// be used in documentation.
	Description string `json:"description,omitempty"`

	// DisplayName: Optional. A concise name for the monitored resource type
	// that might be
	// displayed in user interfaces. It should be a Title Cased Noun
	// Phrase,
	// without any article or other determiners. For example,
	// "Google Cloud SQL Database".
	DisplayName string `json:"displayName,omitempty"`

	// Labels: Required. A set of labels used to describe instances of this
	// monitored
	// resource type.
	// The label key name must follow:
	//
	// * Only upper and lower-case letters, digits and underscores (_) are
	//   allowed.
	// * Label name must start with a letter or digit.
	// * The maximum length of a label name is 100 characters.
	//
	// For example, an individual Google Cloud SQL database is
	// identified by values for the labels `database_id` and `location`.
	Labels []*LabelDescriptor `json:"labels,omitempty"`

	// LaunchStage: Optional. The launch stage of the monitored resource
	// definition.
	//
	// Possible values:
	//   "LAUNCH_STAGE_UNSPECIFIED" - Do not use this default value.
	//   "UNIMPLEMENTED" - The feature is not yet implemented. Users can not
	// use it.
	//   "PRELAUNCH" - Prelaunch features are hidden from users and are only
	// visible internally.
	//   "EARLY_ACCESS" - Early Access features are limited to a closed
	// group of testers. To use
	// these features, you must sign up in advance and sign a Trusted
	// Tester
	// agreement (which includes confidentiality provisions). These features
	// may
	// be unstable, changed in backward-incompatible ways, and are
	// not
	// guaranteed to be released.
	//   "ALPHA" - Alpha is a limited availability test for releases before
	// they are cleared
	// for widespread use. By Alpha, all significant design issues are
	// resolved
	// and we are in the process of verifying functionality. Alpha
	// customers
	// need to apply for access, agree to applicable terms, and have
	// their
	// projects whitelisted. Alpha releases don’t have to be feature
	// complete,
	// no SLAs are provided, and there are no technical support obligations,
	// but
	// they will be far enough along that customers can actually use them
	// in
	// test environments or for limited-use tests -- just like they would
	// in
	// normal production cases.
	//   "BETA" - Beta is the point at which we are ready to open a release
	// for any
	// customer to use. There are no SLA or technical support obligations in
	// a
	// Beta release. Products will be complete from a feature perspective,
	// but
	// may have some open outstanding issues. Beta releases are suitable
	// for
	// limited production use cases.
	//   "GA" - GA features are open to all developers and are considered
	// stable and
	// fully qualified for production use.
	//   "DEPRECATED" - Deprecated features are scheduled to be shut down
	// and removed. For more
	// information, see the “Deprecation Policy” section of our [Terms
	// of
	// Service](https://cloud.google.com/terms/)
	// and the [Google Cloud Platform Subject to the
	// Deprecation
	// Policy](https://cloud.google.com/terms/deprecation) documentation.
	LaunchStage string `json:"launchStage,omitempty"`

	// Name: Optional. The resource name of the monitored resource
	// descriptor:
	// "projects/{project_id}/monitoredResourceDescriptors/{type
	// }" where
	// {type} is the value of the `type` field in this object
	// and
	// {project_id} is a project ID that provides API-specific context
	// for
	// accessing the type.  APIs that do not use project information can use
	// the
	// resource name format "monitoredResourceDescriptors/{type}".
	Name string `json:"name,omitempty"`

	// Type: Required. The monitored resource type. For example, the
	// type
	// `cloudsql_database` represents databases in Google Cloud SQL.
	//
	// All service defined monitored resource types must be prefixed with
	// the
	// service name, in the format of `{service name}/{relative resource
	// name}`.
	// The relative resource name must follow:
	//
	// * Only upper and lower-case letters and digits are allowed.
	// * It must start with upper case character and is recommended to use
	// Upper
	//   Camel Case style.
	// * The maximum number of characters allowed for the
	// relative_resource_name
	//   is 100.
	//
	// Note there are legacy service monitored resources not following this
	// rule.
	Type string `json:"type,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 *MonitoredResourceDescriptor) MarshalJSON() ([]byte, error) {
	type NoMethod MonitoredResourceDescriptor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Monitoring: Monitoring configuration of the service.
//
// The example below shows how to configure monitored resources and
// metrics
// for monitoring. In the example, a monitored resource and two metrics
// are
// defined. The `library.googleapis.com/book/returned_count` metric is
// sent
// to both producer and consumer projects, whereas
// the
// `library.googleapis.com/book/num_overdue` metric is only sent to
// the
// consumer project.
//
//     monitored_resources:
//     - type: library.googleapis.com/Branch
//       display_name: "Library Branch"
//       description: "A branch of a library."
//       launch_stage: GA
//       labels:
//       - key: resource_container
//         description: "The Cloud container (ie. project id) for the
// Branch."
//       - key: location
//         description: "The location of the library branch."
//       - key: branch_id
//         description: "The id of the branch."
//     metrics:
//     - name: library.googleapis.com/book/returned_count
//       display_name: "Books Returned"
//       description: "The count of books that have been returned."
//       launch_stage: GA
//       metric_kind: DELTA
//       value_type: INT64
//       unit: "1"
//       labels:
//       - key: customer_id
//         description: "The id of the customer."
//     - name: library.googleapis.com/book/num_overdue
//       display_name: "Books Overdue"
//       description: "The current number of overdue books."
//       launch_stage: GA
//       metric_kind: GAUGE
//       value_type: INT64
//       unit: "1"
//       labels:
//       - key: customer_id
//         description: "The id of the customer."
//     monitoring:
//       producer_destinations:
//       - monitored_resource: library.googleapis.com/Branch
//         metrics:
//         - library.googleapis.com/book/returned_count
//       consumer_destinations:
//       - monitored_resource: library.googleapis.com/Branch
//         metrics:
//         - library.googleapis.com/book/returned_count
//         - library.googleapis.com/book/num_overdue
type Monitoring struct {
	// ConsumerDestinations: Monitoring configurations for sending metrics
	// to the consumer project.
	// There can be multiple consumer destinations. A monitored resource
	// type may
	// appear in multiple monitoring destinations if different aggregations
	// are
	// needed for different sets of metrics associated with that
	// monitored
	// resource type. A monitored resource and metric pair may only be used
	// once
	// in the Monitoring configuration.
	ConsumerDestinations []*MonitoringDestination `json:"consumerDestinations,omitempty"`

	// ProducerDestinations: Monitoring configurations for sending metrics
	// to the producer project.
	// There can be multiple producer destinations. A monitored resource
	// type may
	// appear in multiple monitoring destinations if different aggregations
	// are
	// needed for different sets of metrics associated with that
	// monitored
	// resource type. A monitored resource and metric pair may only be used
	// once
	// in the Monitoring configuration.
	ProducerDestinations []*MonitoringDestination `json:"producerDestinations,omitempty"`

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

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

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

// MonitoringDestination: Configuration of a specific monitoring
// destination (the producer project
// or the consumer project).
type MonitoringDestination struct {
	// Metrics: Types of the metrics to report to this monitoring
	// destination.
	// Each type must be defined in Service.metrics section.
	Metrics []string `json:"metrics,omitempty"`

	// MonitoredResource: The monitored resource type. The type must be
	// defined in
	// Service.monitored_resources section.
	MonitoredResource string `json:"monitoredResource,omitempty"`

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

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

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

// OAuthRequirements: OAuth scopes are a way to define data and
// permissions on data. For example,
// there are scopes defined for "Read-only access to Google Calendar"
// and
// "Access to Cloud Platform". Users can consent to a scope for an
// application,
// giving it permission to access that data on their behalf.
//
// OAuth scope specifications should be fairly coarse grained; a user
// will need
// to see and understand the text description of what your scope
// means.
//
// In most cases: use one or at most two OAuth scopes for an entire
// family of
// products. If your product has multiple APIs, you should probably be
// sharing
// the OAuth scope across all of those APIs.
//
// When you need finer grained OAuth consent screens: talk with your
// product
// management about how developers will use them in practice.
//
// Please note that even though each of the canonical scopes is enough
// for a
// request to be accepted and passed to the backend, a request can still
// fail
// due to the backend requiring additional scopes or permissions.
type OAuthRequirements struct {
	// CanonicalScopes: The list of publicly documented OAuth scopes that
	// are allowed access. An
	// OAuth token containing any of these scopes will be
	// accepted.
	//
	// Example:
	//
	//      canonical_scopes: https://www.googleapis.com/auth/calendar,
	//                        https://www.googleapis.com/auth/calendar.read
	CanonicalScopes string `json:"canonicalScopes,omitempty"`

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

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

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

// Operation: This resource represents a long-running operation that is
// the result of a
// network API call.
type Operation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress.
	// If `true`, the operation is completed, and either `error` or
	// `response` is
	// available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *Status `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success.
	// If the original
	// method returns no data on success, such as `Delete`, the response
	// is
	// `google.protobuf.Empty`.  If the original method is
	// standard
	// `Get`/`Create`/`Update`, the response should be the resource.  For
	// other
	// methods, the response should have the type `XxxResponse`, where
	// `Xxx`
	// is the original method name.  For example, if the original method
	// name
	// is `TakeSnapshot()`, the inferred response type
	// is
	// `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

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

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

	// NullFields is a list of field names (e.g. "Done") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field 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)
}

// OperationMetadata: The operation metadata returned for the batchend
// services operation.
type OperationMetadata struct {
	// ResourceNames: The full name of the resources that this operation is
	// directly
	// associated with.
	ResourceNames []string `json:"resourceNames,omitempty"`

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

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

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

// Option: A protocol buffer option, which can be attached to a message,
// field,
// enumeration, etc.
type Option struct {
	// Name: The option's name. For protobuf built-in options (options
	// defined in
	// descriptor.proto), this is the short name. For example,
	// "map_entry".
	// For custom options, it should be the fully-qualified name. For
	// example,
	// "google.api.http".
	Name string `json:"name,omitempty"`

	// Value: The option's value packed in an Any message. If the value is a
	// primitive,
	// the corresponding wrapper type defined in
	// google/protobuf/wrappers.proto
	// should be used. If the value is an enum, it should be stored as an
	// int32
	// value using the google.protobuf.Int32Value type.
	Value googleapi.RawMessage `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 *Option) MarshalJSON() ([]byte, error) {
	type NoMethod Option
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OverrideInlineSource: Import data embedded in the request message
type OverrideInlineSource struct {
	// Overrides: The overrides to create.
	// Each override must have a value for 'metric' and 'unit', to
	// specify
	// which metric and which limit the override should be applied to.
	Overrides []*QuotaOverride `json:"overrides,omitempty"`

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

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

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

// Page: Represents a documentation page. A page can contain subpages to
// represent
// nested documentation set structure.
type Page struct {
	// Content: The Markdown content of the page. You can use <code>&#40;==
	// include {path}
	// ==&#41;</code> to include content from a Markdown file.
	Content string `json:"content,omitempty"`

	// Name: The name of the page. It will be used as an identity of the
	// page to
	// generate URI of the page, text of the link to this page in
	// navigation,
	// etc. The full page name (start from the root page name to this
	// page
	// concatenated with `.`) can be used as reference to the page in
	// your
	// documentation. For example:
	// <pre><code>pages:
	// - name: Tutorial
	//   content: &#40;== include tutorial.md ==&#41;
	//   subpages:
	//   - name: Java
	//     content: &#40;== include tutorial_java.md
	// ==&#41;
	// </code></pre>
	// You can reference `Java` page using Markdown reference link
	// syntax:
	// `Java`.
	Name string `json:"name,omitempty"`

	// Subpages: Subpages of this page. The order of subpages specified here
	// will be
	// honored in the generated docset.
	Subpages []*Page `json:"subpages,omitempty"`

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

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

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

// Quota: Quota configuration helps to achieve fairness and budgeting in
// service
// usage.
//
// The metric based quota configuration works this way:
// - The service configuration defines a set of metrics.
// - For API calls, the quota.metric_rules maps methods to metrics with
//   corresponding costs.
// - The quota.limits defines limits on the metrics, which will be used
// for
//   quota checks at runtime.
//
// An example quota configuration in yaml format:
//
//    quota:
//      limits:
//
//      - name: apiWriteQpsPerProject
//        metric: library.googleapis.com/write_calls
//        unit: "1/min/{project}"  # rate limit for consumer projects
//        values:
//          STANDARD: 10000
//
//
//      # The metric rules bind all methods to the read_calls metric,
//      # except for the UpdateBook and DeleteBook methods. These two
// methods
//      # are mapped to the write_calls metric, with the UpdateBook
// method
//      # consuming at twice rate as the DeleteBook method.
//      metric_rules:
//      - selector: "*"
//        metric_costs:
//          library.googleapis.com/read_calls: 1
//      - selector: google.example.library.v1.LibraryService.UpdateBook
//        metric_costs:
//          library.googleapis.com/write_calls: 2
//      - selector: google.example.library.v1.LibraryService.DeleteBook
//        metric_costs:
//          library.googleapis.com/write_calls: 1
//
//  Corresponding Metric definition:
//
//      metrics:
//      - name: library.googleapis.com/read_calls
//        display_name: Read requests
//        metric_kind: DELTA
//        value_type: INT64
//
//      - name: library.googleapis.com/write_calls
//        display_name: Write requests
//        metric_kind: DELTA
//        value_type: INT64
//
//
type Quota struct {
	// Limits: List of `QuotaLimit` definitions for the service.
	Limits []*QuotaLimit `json:"limits,omitempty"`

	// MetricRules: List of `MetricRule` definitions, each one mapping a
	// selected method to one
	// or more metrics.
	MetricRules []*MetricRule `json:"metricRules,omitempty"`

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

	// NullFields is a list of field names (e.g. "Limits") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field 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)
}

// QuotaBucket: A quota bucket is a quota provisioning unit for a
// specific set of dimensions.
type QuotaBucket struct {
	// AdminOverride: Admin override on this quota bucket.
	AdminOverride *QuotaOverride `json:"adminOverride,omitempty"`

	// ConsumerOverride: Consumer override on this quota bucket.
	ConsumerOverride *QuotaOverride `json:"consumerOverride,omitempty"`

	// DefaultLimit: The default limit of this quota bucket, as specified by
	// the service
	// configuration.
	DefaultLimit int64 `json:"defaultLimit,omitempty,string"`

	// Dimensions: The dimensions of this quota bucket.
	//
	// If this map is empty, this is the global bucket, which is the default
	// quota
	// value applied to all requests that do not have a more specific
	// override.
	//
	// If this map is nonempty, the default limit, effective limit, and
	// quota
	// overrides apply only to requests that have the dimensions given in
	// the map.
	//
	// For example, if the map has key "region" and value "us-east-1", then
	// the
	// specified effective limit is only effective in that region, and
	// the
	// specified overrides apply only in that region.
	Dimensions map[string]string `json:"dimensions,omitempty"`

	// EffectiveLimit: The effective limit of this quota bucket. Equal to
	// default_limit if there
	// are no overrides.
	EffectiveLimit int64 `json:"effectiveLimit,omitempty,string"`

	// ProducerOverride: Producer override on this quota bucket.
	ProducerOverride *QuotaOverride `json:"producerOverride,omitempty"`

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

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

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

// QuotaLimit: `QuotaLimit` defines a specific limit that applies over a
// specified duration
// for a limit type. There can be at most one limit for a duration and
// limit
// type combination defined within a `QuotaGroup`.
type QuotaLimit struct {
	// DefaultLimit: Default number of tokens that can be consumed during
	// the specified
	// duration. This is the number of tokens assigned when a
	// client
	// application developer activates the service for his/her
	// project.
	//
	// Specifying a value of 0 will block all requests. This can be used if
	// you
	// are provisioning quota to selected consumers and blocking
	// others.
	// Similarly, a value of -1 will indicate an unlimited quota. No
	// other
	// negative values are allowed.
	//
	// Used by group-based quotas only.
	DefaultLimit int64 `json:"defaultLimit,omitempty,string"`

	// Description: Optional. User-visible, extended description for this
	// quota limit.
	// Should be used only when more context is needed to understand this
	// limit
	// than provided by the limit's display name (see: `display_name`).
	Description string `json:"description,omitempty"`

	// DisplayName: User-visible display name for this limit.
	// Optional. If not set, the UI will provide a default display name
	// based on
	// the quota configuration. This field can be used to override the
	// default
	// display name generated from the configuration.
	DisplayName string `json:"displayName,omitempty"`

	// Duration: Duration of this limit in textual notation. Must be "100s"
	// or "1d".
	//
	// Used by group-based quotas only.
	Duration string `json:"duration,omitempty"`

	// FreeTier: Free tier value displayed in the Developers Console for
	// this limit.
	// The free tier is the number of tokens that will be subtracted from
	// the
	// billed amount when billing is enabled.
	// This field can only be set on a limit with duration "1d", in a
	// billable
	// group; it is invalid on any other limit. If this field is not set,
	// it
	// defaults to 0, indicating that there is no free tier for this
	// service.
	//
	// Used by group-based quotas only.
	FreeTier int64 `json:"freeTier,omitempty,string"`

	// MaxLimit: Maximum number of tokens that can be consumed during the
	// specified
	// duration. Client application developers can override the default
	// limit up
	// to this maximum. If specified, this value cannot be set to a value
	// less
	// than the default limit. If not specified, it is set to the default
	// limit.
	//
	// To allow clients to apply overrides with no upper bound, set this to
	// -1,
	// indicating unlimited maximum quota.
	//
	// Used by group-based quotas only.
	MaxLimit int64 `json:"maxLimit,omitempty,string"`

	// Metric: The name of the metric this quota limit applies to. The quota
	// limits with
	// the same metric will be checked together during runtime. The metric
	// must be
	// defined within the service config.
	Metric string `json:"metric,omitempty"`

	// Name: Name of the quota limit.
	//
	// The name must be provided, and it must be unique within the service.
	// The
	// name can only include alphanumeric characters as well as '-'.
	//
	// The maximum length of the limit name is 64 characters.
	Name string `json:"name,omitempty"`

	// Unit: Specify the unit of the quota limit. It uses the same syntax
	// as
	// Metric.unit. The supported unit kinds are determined by the
	// quota
	// backend system.
	//
	// Here are some examples:
	// * "1/min/{project}" for quota per minute per project.
	//
	// Note: the order of unit components is insignificant.
	// The "1" at the beginning is required to follow the metric unit
	// syntax.
	Unit string `json:"unit,omitempty"`

	// Values: Tiered limit values. You must specify this as a key:value
	// pair, with an
	// integer value that is the maximum number of requests allowed for
	// the
	// specified unit. Currently only STANDARD is supported.
	Values map[string]string `json:"values,omitempty"`

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

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

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

// QuotaOverride: A quota override
type QuotaOverride struct {
	// AdminOverrideAncestor: The resource name of the ancestor that
	// requested the override. For example:
	// "organizations/12345" or "folders/67890".
	// Used by admin overrides only.
	AdminOverrideAncestor string `json:"adminOverrideAncestor,omitempty"`

	// Dimensions: If this map is nonempty, then this override applies only
	// to specific values
	// for dimensions defined in the limit unit.
	//
	// For example, an override on a limit with the unit
	// 1/{project}/{region}
	// could contain an entry with the key "region" and the value
	// "us-east-1";
	// the override is only applied to quota consumed in that region.
	//
	// This map has the following restrictions:
	//
	// *   Keys that are not defined in the limit's unit are not valid
	// keys.
	//     Any string appearing in {brackets} in the unit (besides {project}
	// or
	//     {user}) is a defined key.
	// *   "project" is not a valid key; the project is already specified
	// in
	//     the parent resource name.
	// *   "user" is not a valid key; the API does not support quota
	// overrides
	//     that apply only to a specific user.
	// *   If "region" appears as a key, its value must be a valid Cloud
	// region.
	// *   If "zone" appears as a key, its value must be a valid Cloud
	// zone.
	// *   If any valid key other than "region" or "zone" appears in the
	// map, then
	//     all valid keys other than "region" or "zone" must also appear in
	// the
	//     map.
	Dimensions map[string]string `json:"dimensions,omitempty"`

	// Metric: The name of the metric to which this override applies.
	//
	// An example name would be:
	// `compute.googleapis.com/cpus`
	Metric string `json:"metric,omitempty"`

	// Name: The resource name of the override.
	// This name is generated by the server when the override is
	// created.
	//
	// Example names would
	// be:
	// `projects/123/services/compute.googleapis.com/consumerQuotaMetrics
	// /compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/adminOverrid
	// es/4a3f2c1d`
	// `projects/123/services/compute.googleapis.com/consumerQuo
	// taMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/con
	// sumerOverrides/4a3f2c1d`
	//
	// The resource name is intended to be opaque and should not be parsed
	// for
	// its component strings, since its representation could change in the
	// future.
	Name string `json:"name,omitempty"`

	// OverrideValue: The overriding quota limit value.
	// Can be any nonnegative integer, or -1 (unlimited quota).
	OverrideValue int64 `json:"overrideValue,omitempty,string"`

	// Unit: The limit unit of the limit to which this override applies.
	//
	// An example unit would be:
	// `1/{project}/{region}`
	// Note that `{project}` and `{region}` are not placeholders in this
	// example;
	// the literal characters `{` and `}` occur in the string.
	Unit string `json:"unit,omitempty"`

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

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

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

// Service: A service that is available for use by the consumer.
type Service struct {
	// Config: The service configuration of the available service.
	// Some fields may be filtered out of the configuration in responses
	// to
	// the `ListServices` method. These fields are present only in responses
	// to
	// the `GetService` method.
	Config *ServiceConfig `json:"config,omitempty"`

	// Name: The resource name of the consumer and service.
	//
	// A valid name would be:
	// - projects/123/services/serviceusage.googleapis.com
	Name string `json:"name,omitempty"`

	// Parent: The resource name of the consumer.
	//
	// A valid name would be:
	// - projects/123
	Parent string `json:"parent,omitempty"`

	// State: Whether or not the service has been enabled for use by the
	// consumer.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - The default value, which indicates that the
	// enabled state of the service
	// is unspecified or not meaningful. Currently, all consumers other
	// than
	// projects (such as folders and organizations) are always in this
	// state.
	//   "DISABLED" - The service cannot be used by this consumer. It has
	// either been explicitly
	// disabled, or has never been enabled.
	//   "ENABLED" - The service has been explicitly enabled for use by this
	// consumer.
	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. "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 *Service) MarshalJSON() ([]byte, error) {
	type NoMethod Service
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ServiceConfig: The configuration of the service.
type ServiceConfig struct {
	// Apis: A list of API interfaces exported by this service. Contains
	// only the names,
	// versions, and method names of the interfaces.
	Apis []*Api `json:"apis,omitempty"`

	// Authentication: Auth configuration. Contains only the OAuth rules.
	Authentication *Authentication `json:"authentication,omitempty"`

	// Documentation: Additional API documentation. Contains only the
	// summary and the
	// documentation URL.
	Documentation *Documentation `json:"documentation,omitempty"`

	// Endpoints: Configuration for network endpoints. Contains only the
	// names and aliases
	// of the endpoints.
	Endpoints []*Endpoint `json:"endpoints,omitempty"`

	// Name: The DNS address at which this service is available.
	//
	// An example DNS address would be:
	// `calendar.googleapis.com`.
	Name string `json:"name,omitempty"`

	// Quota: Quota configuration.
	Quota *Quota `json:"quota,omitempty"`

	// Title: The product title for this service.
	Title string `json:"title,omitempty"`

	// Usage: Configuration controlling usage of this service.
	Usage *Usage `json:"usage,omitempty"`

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

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

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

// ServiceIdentity: Service identity for a service. This is the identity
// that service producer
// should use to access consumer resources.
type ServiceIdentity struct {
	// Email: The email address of the service account that a service
	// producer would use
	// to access consumer resources.
	Email string `json:"email,omitempty"`

	// UniqueId: The unique and stable id of the service
	// account.
	// https://cloud.google.com/iam/reference/rest/v1/projects.servi
	// ceAccounts#ServiceAccount
	UniqueId string `json:"uniqueId,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 *ServiceIdentity) MarshalJSON() ([]byte, error) {
	type NoMethod ServiceIdentity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SourceContext: `SourceContext` represents information about the
// source of a
// protobuf element, like the file in which it is defined.
type SourceContext struct {
	// FileName: The path-qualified name of the .proto file that contained
	// the associated
	// protobuf element.  For example:
	// "google/protobuf/source_context.proto".
	FileName string `json:"fileName,omitempty"`

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

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

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

// SourceInfo: Source information used to create a Service Config
type SourceInfo struct {
	// SourceFiles: All files used during config generation.
	SourceFiles []googleapi.RawMessage `json:"sourceFiles,omitempty"`

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

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

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

// Status: The `Status` type defines a logical error model that is
// suitable for
// different programming environments, including REST APIs and RPC APIs.
// It is
// used by [gRPC](https://github.com/grpc). Each `Status` message
// contains
// three pieces of data: error code, error message, and error
// details.
//
// You can find out more about this error model and how to work with it
// in the
// [API Design Guide](https://cloud.google.com/apis/design/errors).
type Status struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details.  There is a
	// common set of
	// message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any
	// user-facing error message should be localized and sent in
	// the
	// google.rpc.Status.details field, or localized by the client.
	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 *Status) MarshalJSON() ([]byte, error) {
	type NoMethod Status
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SystemParameter: Define a parameter's name and location. The
// parameter may be passed as either
// an HTTP header or a URL query parameter, and if both are passed the
// behavior
// is implementation-dependent.
type SystemParameter struct {
	// HttpHeader: Define the HTTP header name to use for the parameter. It
	// is case
	// insensitive.
	HttpHeader string `json:"httpHeader,omitempty"`

	// Name: Define the name of the parameter, such as "api_key" . It is
	// case sensitive.
	Name string `json:"name,omitempty"`

	// UrlQueryParameter: Define the URL query parameter name to use for the
	// parameter. It is case
	// sensitive.
	UrlQueryParameter string `json:"urlQueryParameter,omitempty"`

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

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

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

// SystemParameterRule: Define a system parameter rule mapping system
// parameter definitions to
// methods.
type SystemParameterRule struct {
	// Parameters: Define parameters. Multiple names may be defined for a
	// parameter.
	// For a given method call, only one of them should be used. If
	// multiple
	// names are used the behavior is implementation-dependent.
	// If none of the specified names are present the behavior
	// is
	// parameter-dependent.
	Parameters []*SystemParameter `json:"parameters,omitempty"`

	// Selector: Selects the methods to which this rule applies. Use '*' to
	// indicate all
	// methods in all APIs.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

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

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

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

// SystemParameters: ### System parameter configuration
//
// A system parameter is a special kind of parameter defined by the
// API
// system, not by an individual API. It is typically mapped to an HTTP
// header
// and/or a URL query parameter. This configuration specifies which
// methods
// change the names of the system parameters.
type SystemParameters struct {
	// Rules: Define system parameters.
	//
	// The parameters defined here will override the default
	// parameters
	// implemented by the system. If this field is missing from the
	// service
	// config, default system parameters will be used. Default system
	// parameters
	// and names is implementation-dependent.
	//
	// Example: define api key for all methods
	//
	//     system_parameters
	//       rules:
	//         - selector: "*"
	//           parameters:
	//             - name: api_key
	//               url_query_parameter: api_key
	//
	//
	// Example: define 2 api key names for a specific method.
	//
	//     system_parameters
	//       rules:
	//         - selector: "/ListShelves"
	//           parameters:
	//             - name: api_key
	//               http_header: Api-Key1
	//             - name: api_key
	//               http_header: Api-Key2
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*SystemParameterRule `json:"rules,omitempty"`

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

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

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

// Type: A protocol buffer message type.
type Type struct {
	// Fields: The list of fields.
	Fields []*Field `json:"fields,omitempty"`

	// Name: The fully qualified message name.
	Name string `json:"name,omitempty"`

	// Oneofs: The list of types appearing in `oneof` definitions in this
	// type.
	Oneofs []string `json:"oneofs,omitempty"`

	// Options: The protocol buffer options.
	Options []*Option `json:"options,omitempty"`

	// SourceContext: The source context.
	SourceContext *SourceContext `json:"sourceContext,omitempty"`

	// Syntax: The source syntax.
	//
	// Possible values:
	//   "SYNTAX_PROTO2" - Syntax `proto2`.
	//   "SYNTAX_PROTO3" - Syntax `proto3`.
	Syntax string `json:"syntax,omitempty"`

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

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

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

// Usage: Configuration controlling usage of a service.
type Usage struct {
	// ProducerNotificationChannel: The full resource name of a channel used
	// for sending notifications to the
	// service producer.
	//
	// Google Service Management currently only supports
	// [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) as a
	// notification
	// channel. To use Google Cloud Pub/Sub as the channel, this must be the
	// name
	// of a Cloud Pub/Sub topic that uses the Cloud Pub/Sub topic name
	// format
	// documented in https://cloud.google.com/pubsub/docs/overview.
	ProducerNotificationChannel string `json:"producerNotificationChannel,omitempty"`

	// Requirements: Requirements that must be satisfied before a consumer
	// project can use the
	// service. Each requirement is of the form
	// <service.name>/<requirement-id>;
	// for example 'serviceusage.googleapis.com/billing-enabled'.
	Requirements []string `json:"requirements,omitempty"`

	// Rules: A list of usage rules that apply to individual API
	// methods.
	//
	// **NOTE:** All service configuration rules follow "last one wins"
	// order.
	Rules []*UsageRule `json:"rules,omitempty"`

	// ServiceIdentity: The configuration of a per-product per-project
	// service identity.
	ServiceIdentity *GoogleApiServiceIdentity `json:"serviceIdentity,omitempty"`

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

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

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

// UsageRule: Usage configuration rules for the service.
//
// NOTE: Under development.
//
//
// Use this rule to configure unregistered calls for the service.
// Unregistered
// calls are calls that do not contain consumer project
// identity.
// (Example: calls that do not contain an API key).
// By default, API methods do not allow unregistered calls, and each
// method call
// must be identified by a consumer project identity. Use this rule
// to
// allow/disallow unregistered calls.
//
// Example of an API that wants to allow unregistered calls for entire
// service.
//
//     usage:
//       rules:
//       - selector: "*"
//         allow_unregistered_calls: true
//
// Example of a method that wants to allow unregistered calls.
//
//     usage:
//       rules:
//       - selector:
// "google.example.library.v1.LibraryService.CreateBook"
//         allow_unregistered_calls: true
type UsageRule struct {
	// AllowUnregisteredCalls: If true, the selected method allows
	// unregistered calls, e.g. calls
	// that don't identify any user or application.
	AllowUnregisteredCalls bool `json:"allowUnregisteredCalls,omitempty"`

	// Selector: Selects the methods to which this rule applies. Use '*' to
	// indicate all
	// methods in all APIs.
	//
	// Refer to selector for syntax details.
	Selector string `json:"selector,omitempty"`

	// SkipServiceControl: If true, the selected method should skip service
	// control and the control
	// plane features, such as quota and billing, will not be
	// available.
	// This flag is used by Google Cloud Endpoints to bypass checks for
	// internal
	// methods, such as service health check methods.
	SkipServiceControl bool `json:"skipServiceControl,omitempty"`

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

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

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

// method id "serviceusage.operations.get":

type OperationsGetCall struct {
	s            *APIService
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the latest state of a long-running operation.  Clients can
// use this
// method to poll the operation result at intervals as recommended by
// the API
// service.
func (r *OperationsService) Get(name string) *OperationsGetCall {
	c := &OperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperationsGetCall) Fields(s ...googleapi.Field) *OperationsGetCall {
	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 *OperationsGetCall) IfNoneMatch(entityTag string) *OperationsGetCall {
	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 *OperationsGetCall) Context(ctx context.Context) *OperationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.operations.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 *OperationsGetCall) 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": "Gets the latest state of a long-running operation.  Clients can use this\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "flatPath": "v1beta1/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.operations.list":

type OperationsListCall struct {
	s            *APIService
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists operations that match the specified filter in the
// request. If the
// server doesn't support this method, it returns
// `UNIMPLEMENTED`.
//
// NOTE: the `name` binding allows API services to override the
// binding
// to use different resource name schemes, such as `users/*/operations`.
// To
// override the binding, API services can add a binding such
// as
// "/v1/{name=users/*}/operations" to their service configuration.
// For backwards compatibility, the default name includes the
// operations
// collection id, however overriding users must ensure the name
// binding
// is the parent resource, without the operations collection id.
func (r *OperationsService) List() *OperationsListCall {
	c := &OperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *OperationsListCall) Filter(filter string) *OperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// Name sets the optional parameter "name": The name of the operation's
// parent resource.
func (c *OperationsListCall) Name(name string) *OperationsListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *OperationsListCall) PageSize(pageSize int64) *OperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *OperationsListCall) PageToken(pageToken string) *OperationsListCall {
	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 *OperationsListCall) Fields(s ...googleapi.Field) *OperationsListCall {
	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 *OperationsListCall) IfNoneMatch(entityTag string) *OperationsListCall {
	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 *OperationsListCall) Context(ctx context.Context) *OperationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.operations.list" call.
// Exactly one of *ListOperationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListOperationsResponse{
		ServerResponse: googleapi.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 operations that match the specified filter in the request. If the\nserver doesn't support this method, it returns `UNIMPLEMENTED`.\n\nNOTE: the `name` binding allows API services to override the binding\nto use different resource name schemes, such as `users/*/operations`. To\noverride the binding, API services can add a binding such as\n`\"/v1/{name=users/*}/operations\"` to their service configuration.\nFor backwards compatibility, the default name includes the operations\ncollection id, however overriding users must ensure the name binding\nis the parent resource, without the operations collection id.",
	//   "flatPath": "v1beta1/operations",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.operations.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/operations",
	//   "response": {
	//     "$ref": "ListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// 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 *OperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) 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 "serviceusage.services.batchEnable":

type ServicesBatchEnableCall struct {
	s                          *APIService
	parent                     string
	batchenableservicesrequest *BatchEnableServicesRequest
	urlParams_                 gensupport.URLParams
	ctx_                       context.Context
	header_                    http.Header
}

// BatchEnable: Enable multiple services on a project. The operation is
// atomic: if enabling
// any service fails, then the entire batch fails, and no state changes
// occur.
//
// Operation<response: google.protobuf.Empty>
func (r *ServicesService) BatchEnable(parent string, batchenableservicesrequest *BatchEnableServicesRequest) *ServicesBatchEnableCall {
	c := &ServicesBatchEnableCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.batchenableservicesrequest = batchenableservicesrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesBatchEnableCall) Fields(s ...googleapi.Field) *ServicesBatchEnableCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesBatchEnableCall) Context(ctx context.Context) *ServicesBatchEnableCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesBatchEnableCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesBatchEnableCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.batchenableservicesrequest)
	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, "v1beta1/{+parent}/services:batchEnable")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.batchEnable" 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 *ServicesBatchEnableCall) 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 multiple services on a project. The operation is atomic: if enabling\nany service fails, then the entire batch fails, and no state changes occur.\n\nOperation\u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services:batchEnable",
	//   "httpMethod": "POST",
	//   "id": "serviceusage.services.batchEnable",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Parent to enable services on.\n\nAn example name would be:\n`projects/123`\nwhere `123` is the project number (not project ID).\n\nThe `BatchEnableServices` method currently only supports projects.",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/services:batchEnable",
	//   "request": {
	//     "$ref": "BatchEnableServicesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.disable":

type ServicesDisableCall struct {
	s                     *APIService
	name                  string
	disableservicerequest *DisableServiceRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Disable: Disable a service so that it can no longer be used with a
// project.
// This prevents unintended usage that may cause unexpected
// billing
// charges or security leaks.
//
// It is not valid to call the disable method on a service that is
// not
// currently enabled. Callers will receive a `FAILED_PRECONDITION`
// status if
// the target service is not currently enabled.
//
// Operation<response: google.protobuf.Empty>
func (r *ServicesService) Disable(name string, disableservicerequest *DisableServiceRequest) *ServicesDisableCall {
	c := &ServicesDisableCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.disableservicerequest = disableservicerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesDisableCall) Fields(s ...googleapi.Field) *ServicesDisableCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesDisableCall) Context(ctx context.Context) *ServicesDisableCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesDisableCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesDisableCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.disableservicerequest)
	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, "v1beta1/{+name}:disable")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.disable" 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 *ServicesDisableCall) 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 so that it can no longer be used with a project.\nThis prevents unintended usage that may cause unexpected billing\ncharges or security leaks.\n\nIt is not valid to call the disable method on a service that is not\ncurrently enabled. Callers will receive a `FAILED_PRECONDITION` status if\nthe target service is not currently enabled.\n\nOperation\u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}:disable",
	//   "httpMethod": "POST",
	//   "id": "serviceusage.services.disable",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the consumer and service to disable the service on.\n\nThe enable and disable methods currently only support projects.\n\nAn example name would be:\n`projects/123/services/serviceusage.googleapis.com`\nwhere `123` is the project number (not project ID).",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}:disable",
	//   "request": {
	//     "$ref": "DisableServiceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.enable":

type ServicesEnableCall struct {
	s                    *APIService
	name                 string
	enableservicerequest *EnableServiceRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Enable: Enable a service so that it can be used with a
// project.
//
// Operation<response: google.protobuf.Empty>
func (r *ServicesService) Enable(name string, enableservicerequest *EnableServiceRequest) *ServicesEnableCall {
	c := &ServicesEnableCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.enableservicerequest = enableservicerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesEnableCall) Fields(s ...googleapi.Field) *ServicesEnableCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesEnableCall) Context(ctx context.Context) *ServicesEnableCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesEnableCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesEnableCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.enableservicerequest)
	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, "v1beta1/{+name}:enable")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.enable" 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 *ServicesEnableCall) 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 a service so that it can be used with a project.\n\nOperation\u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}:enable",
	//   "httpMethod": "POST",
	//   "id": "serviceusage.services.enable",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the consumer and service to enable the service on.\n\nThe `EnableService` and `DisableService` methods currently only support\nprojects.\n\nEnabling a service requires that the service is public or is shared with\nthe user enabling the service.\n\nAn example name would be:\n`projects/123/services/serviceusage.googleapis.com`\nwhere `123` is the project number (not project ID).",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}:enable",
	//   "request": {
	//     "$ref": "EnableServiceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.generateServiceIdentity":

type ServicesGenerateServiceIdentityCall struct {
	s          *APIService
	parent     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// GenerateServiceIdentity: Generate service identity for service.
func (r *ServicesService) GenerateServiceIdentity(parent string) *ServicesGenerateServiceIdentityCall {
	c := &ServicesGenerateServiceIdentityCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesGenerateServiceIdentityCall) Fields(s ...googleapi.Field) *ServicesGenerateServiceIdentityCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesGenerateServiceIdentityCall) Context(ctx context.Context) *ServicesGenerateServiceIdentityCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesGenerateServiceIdentityCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesGenerateServiceIdentityCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+parent}:generateServiceIdentity")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.generateServiceIdentity" 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 *ServicesGenerateServiceIdentityCall) 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": "Generate service identity for service.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}:generateServiceIdentity",
	//   "httpMethod": "POST",
	//   "id": "serviceusage.services.generateServiceIdentity",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Name of the consumer and service to generate an identity for.\n\nThe `GenerateServiceIdentity` methods currently only support projects.\n\nAn example name would be:\n`projects/123/services/example.googleapis.com` where `123` is the\nproject number.",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}:generateServiceIdentity",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.get":

type ServicesGetCall struct {
	s            *APIService
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the service configuration and enabled state for a given
// service.
func (r *ServicesService) Get(name string) *ServicesGetCall {
	c := &ServicesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesGetCall) Fields(s ...googleapi.Field) *ServicesGetCall {
	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 *ServicesGetCall) IfNoneMatch(entityTag string) *ServicesGetCall {
	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 *ServicesGetCall) Context(ctx context.Context) *ServicesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.get" call.
// Exactly one of *Service or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Service.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ServicesGetCall) Do(opts ...googleapi.CallOption) (*Service, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Service{
		ServerResponse: googleapi.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 service configuration and enabled state for a given service.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.services.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the consumer and service to get the `ConsumerState` for.\n\nAn example name would be:\n`projects/123/services/serviceusage.googleapis.com`\nwhere `123` is the project number (not project ID).",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "serviceusage.services.list":

type ServicesListCall struct {
	s            *APIService
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List all services available to the specified project, and the
// current
// state of those services with respect to the project. The list
// includes
// all public services, all services for which the calling user has
// the
// `servicemanagement.services.bind` permission, and all services that
// have
// already been enabled on the project. The list can be filtered to
// only include services in a specific state, for example to only
// include
// services enabled on the project.
func (r *ServicesService) List(parent string) *ServicesListCall {
	c := &ServicesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Only list services that
// conform to the given filter.
// The allowed filter strings are `state:ENABLED` and `state:DISABLED`.
func (c *ServicesListCall) Filter(filter string) *ServicesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested size of
// the next page of data.
// Requested page size cannot exceed 200.
//  If not set, the default page size is 50.
func (c *ServicesListCall) PageSize(pageSize int64) *ServicesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token identifying
// which result to start with, which is returned by a
// previous list call.
func (c *ServicesListCall) PageToken(pageToken string) *ServicesListCall {
	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 *ServicesListCall) Fields(s ...googleapi.Field) *ServicesListCall {
	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 *ServicesListCall) IfNoneMatch(entityTag string) *ServicesListCall {
	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 *ServicesListCall) Context(ctx context.Context) *ServicesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+parent}/services")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.list" call.
// Exactly one of *ListServicesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListServicesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesListCall) Do(opts ...googleapi.CallOption) (*ListServicesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListServicesResponse{
		ServerResponse: googleapi.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 services available to the specified project, and the current\nstate of those services with respect to the project. The list includes\nall public services, all services for which the calling user has the\n`servicemanagement.services.bind` permission, and all services that have\nalready been enabled on the project. The list can be filtered to\nonly include services in a specific state, for example to only include\nservices enabled on the project.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.services.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Only list services that conform to the given filter.\nThe allowed filter strings are `state:ENABLED` and `state:DISABLED`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested size of the next page of data.\nRequested page size cannot exceed 200.\n If not set, the default page size is 50.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token identifying which result to start with, which is returned by a\nprevious list call.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Parent to search for services on.\n\nAn example name would be:\n`projects/123`\nwhere `123` is the project number (not project ID).",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/services",
	//   "response": {
	//     "$ref": "ListServicesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *ServicesListCall) Pages(ctx context.Context, f func(*ListServicesResponse) 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 "serviceusage.services.consumerQuotaMetrics.get":

type ServicesConsumerQuotaMetricsGetCall struct {
	s            *APIService
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves a summary of quota information for a specific quota
// metric
func (r *ServicesConsumerQuotaMetricsService) Get(name string) *ServicesConsumerQuotaMetricsGetCall {
	c := &ServicesConsumerQuotaMetricsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// View sets the optional parameter "view": Specifies the level of
// detail for quota information in the response.
//
// Possible values:
//   "QUOTA_VIEW_UNSPECIFIED"
//   "BASIC"
//   "FULL"
func (c *ServicesConsumerQuotaMetricsGetCall) View(view string) *ServicesConsumerQuotaMetricsGetCall {
	c.urlParams_.Set("view", view)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsGetCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsGetCall {
	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 *ServicesConsumerQuotaMetricsGetCall) IfNoneMatch(entityTag string) *ServicesConsumerQuotaMetricsGetCall {
	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 *ServicesConsumerQuotaMetricsGetCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.get" call.
// Exactly one of *ConsumerQuotaMetric or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ConsumerQuotaMetric.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesConsumerQuotaMetricsGetCall) Do(opts ...googleapi.CallOption) (*ConsumerQuotaMetric, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ConsumerQuotaMetric{
		ServerResponse: googleapi.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 summary of quota information for a specific quota metric",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.services.consumerQuotaMetrics.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The resource name of the quota limit.\n\nAn example name would be:\nprojects/123/services/serviceusage.googleapis.com/quotas/metrics/serviceusage.googleapis.com%2Fmutate_requests",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Specifies the level of detail for quota information in the response.",
	//       "enum": [
	//         "QUOTA_VIEW_UNSPECIFIED",
	//         "BASIC",
	//         "FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "ConsumerQuotaMetric"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.importConsumerOverrides":

type ServicesConsumerQuotaMetricsImportConsumerOverridesCall struct {
	s                              *APIService
	parent                         string
	importconsumeroverridesrequest *ImportConsumerOverridesRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// ImportConsumerOverrides: Create or update multiple consumer overrides
// atomically, all on the
// same consumer, but on many different metrics or limits.
// The name field in the quota override message should not be set.
func (r *ServicesConsumerQuotaMetricsService) ImportConsumerOverrides(parent string, importconsumeroverridesrequest *ImportConsumerOverridesRequest) *ServicesConsumerQuotaMetricsImportConsumerOverridesCall {
	c := &ServicesConsumerQuotaMetricsImportConsumerOverridesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.importconsumeroverridesrequest = importconsumeroverridesrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsImportConsumerOverridesCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsImportConsumerOverridesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesConsumerQuotaMetricsImportConsumerOverridesCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsImportConsumerOverridesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsImportConsumerOverridesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsImportConsumerOverridesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.importconsumeroverridesrequest)
	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, "v1beta1/{+parent}/consumerQuotaMetrics:importConsumerOverrides")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.importConsumerOverrides" 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 *ServicesConsumerQuotaMetricsImportConsumerOverridesCall) 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 or update multiple consumer overrides atomically, all on the\nsame consumer, but on many different metrics or limits.\nThe name field in the quota override message should not be set.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics:importConsumerOverrides",
	//   "httpMethod": "POST",
	//   "id": "serviceusage.services.consumerQuotaMetrics.importConsumerOverrides",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The resource name of the consumer.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/consumerQuotaMetrics:importConsumerOverrides",
	//   "request": {
	//     "$ref": "ImportConsumerOverridesRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.list":

type ServicesConsumerQuotaMetricsListCall struct {
	s            *APIService
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a summary of all quota information visible to the
// service
// consumer, organized by service metric. Each metric includes
// information
// about all of its defined limits. Each limit includes the
// limit
// configuration (quota unit, preciseness, default value), the
// current
// effective limit value, and all of the overrides applied to the limit.
func (r *ServicesConsumerQuotaMetricsService) List(parent string) *ServicesConsumerQuotaMetricsListCall {
	c := &ServicesConsumerQuotaMetricsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Requested size of
// the next page of data.
func (c *ServicesConsumerQuotaMetricsListCall) PageSize(pageSize int64) *ServicesConsumerQuotaMetricsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token identifying
// which result to start with; returned by a previous list
// call.
func (c *ServicesConsumerQuotaMetricsListCall) PageToken(pageToken string) *ServicesConsumerQuotaMetricsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// View sets the optional parameter "view": Specifies the level of
// detail for quota information in the response.
//
// Possible values:
//   "QUOTA_VIEW_UNSPECIFIED"
//   "BASIC"
//   "FULL"
func (c *ServicesConsumerQuotaMetricsListCall) View(view string) *ServicesConsumerQuotaMetricsListCall {
	c.urlParams_.Set("view", view)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsListCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsListCall {
	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 *ServicesConsumerQuotaMetricsListCall) IfNoneMatch(entityTag string) *ServicesConsumerQuotaMetricsListCall {
	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 *ServicesConsumerQuotaMetricsListCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+parent}/consumerQuotaMetrics")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.list" call.
// Exactly one of *ListConsumerQuotaMetricsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListConsumerQuotaMetricsResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesConsumerQuotaMetricsListCall) Do(opts ...googleapi.CallOption) (*ListConsumerQuotaMetricsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListConsumerQuotaMetricsResponse{
		ServerResponse: googleapi.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 summary of all quota information visible to the service\nconsumer, organized by service metric. Each metric includes information\nabout all of its defined limits. Each limit includes the limit\nconfiguration (quota unit, preciseness, default value), the current\neffective limit value, and all of the overrides applied to the limit.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.services.consumerQuotaMetrics.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Requested size of the next page of data.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token identifying which result to start with; returned by a previous list\ncall.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Parent of the quotas resource.\n\nSome example names would be:\nprojects/123/services/serviceconsumermanagement.googleapis.com\nfolders/345/services/serviceconsumermanagement.googleapis.com\norganizations/456/services/serviceconsumermanagement.googleapis.com",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Specifies the level of detail for quota information in the response.",
	//       "enum": [
	//         "QUOTA_VIEW_UNSPECIFIED",
	//         "BASIC",
	//         "FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/consumerQuotaMetrics",
	//   "response": {
	//     "$ref": "ListConsumerQuotaMetricsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *ServicesConsumerQuotaMetricsListCall) Pages(ctx context.Context, f func(*ListConsumerQuotaMetricsResponse) 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 "serviceusage.services.consumerQuotaMetrics.limits.get":

type ServicesConsumerQuotaMetricsLimitsGetCall struct {
	s            *APIService
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves a summary of quota information for a specific quota
// limit.
func (r *ServicesConsumerQuotaMetricsLimitsService) Get(name string) *ServicesConsumerQuotaMetricsLimitsGetCall {
	c := &ServicesConsumerQuotaMetricsLimitsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// View sets the optional parameter "view": Specifies the level of
// detail for quota information in the response.
//
// Possible values:
//   "QUOTA_VIEW_UNSPECIFIED"
//   "BASIC"
//   "FULL"
func (c *ServicesConsumerQuotaMetricsLimitsGetCall) View(view string) *ServicesConsumerQuotaMetricsLimitsGetCall {
	c.urlParams_.Set("view", view)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsLimitsGetCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsGetCall {
	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 *ServicesConsumerQuotaMetricsLimitsGetCall) IfNoneMatch(entityTag string) *ServicesConsumerQuotaMetricsLimitsGetCall {
	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 *ServicesConsumerQuotaMetricsLimitsGetCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.get" call.
// Exactly one of *ConsumerQuotaLimit or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ConsumerQuotaLimit.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesConsumerQuotaMetricsLimitsGetCall) Do(opts ...googleapi.CallOption) (*ConsumerQuotaLimit, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ConsumerQuotaLimit{
		ServerResponse: googleapi.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 summary of quota information for a specific quota limit.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The resource name of the quota limit.\n\nUse the quota limit resource name returned by previous\nListConsumerQuotaMetrics and GetConsumerQuotaMetric API calls.",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Specifies the level of detail for quota information in the response.",
	//       "enum": [
	//         "QUOTA_VIEW_UNSPECIFIED",
	//         "BASIC",
	//         "FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "ConsumerQuotaLimit"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.create":

type ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall struct {
	s             *APIService
	parent        string
	quotaoverride *QuotaOverride
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Create: Creates an admin override.
// An admin override is applied by an administrator of a parent folder
// or
// parent organization of the consumer receiving the override. An
// admin
// override is intended to limit the amount of quota the consumer can
// use out
// of the total quota pool allocated to all children of the folder
// or
// organization.
func (r *ServicesConsumerQuotaMetricsLimitsAdminOverridesService) Create(parent string, quotaoverride *QuotaOverride) *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall {
	c := &ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.quotaoverride = quotaoverride
	return c
}

// Force sets the optional parameter "force": Whether to force the
// creation of the quota override.
// If creating an override would cause the effective quota for the
// consumer to
// decrease by more than 10 percent, the call is rejected, as a safety
// measure
// to avoid accidentally decreasing quota too quickly. Setting the
// force
// parameter to true ignores this restriction.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall) Force(force bool) *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.quotaoverride)
	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, "v1beta1/{+parent}/adminOverrides")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.create" 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 *ServicesConsumerQuotaMetricsLimitsAdminOverridesCreateCall) 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 admin override.\nAn admin override is applied by an administrator of a parent folder or\nparent organization of the consumer receiving the override. An admin\noverride is intended to limit the amount of quota the consumer can use out\nof the total quota pool allocated to all children of the folder or\norganization.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/adminOverrides",
	//   "httpMethod": "POST",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "force": {
	//       "description": "Whether to force the creation of the quota override.\nIf creating an override would cause the effective quota for the consumer to\ndecrease by more than 10 percent, the call is rejected, as a safety measure\nto avoid accidentally decreasing quota too quickly. Setting the force\nparameter to true ignores this restriction.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "The resource name of the parent quota limit, returned by a\nListConsumerQuotaMetrics or GetConsumerQuotaMetric call.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/adminOverrides",
	//   "request": {
	//     "$ref": "QuotaOverride"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.delete":

type ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall struct {
	s          *APIService
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an admin override.
func (r *ServicesConsumerQuotaMetricsLimitsAdminOverridesService) Delete(name string) *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall {
	c := &ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Force sets the optional parameter "force": Whether to force the
// deletion of the quota override.
// If deleting an override would cause the effective quota for the
// consumer to
// decrease by more than 10 percent, the call is rejected, as a safety
// measure
// to avoid accidentally decreasing quota too quickly. Setting the
// force
// parameter to true ignores this restriction.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall) Force(force bool) *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.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 *ServicesConsumerQuotaMetricsLimitsAdminOverridesDeleteCall) 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 admin override.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/adminOverrides/{adminOverridesId}",
	//   "httpMethod": "DELETE",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "force": {
	//       "description": "Whether to force the deletion of the quota override.\nIf deleting an override would cause the effective quota for the consumer to\ndecrease by more than 10 percent, the call is rejected, as a safety measure\nto avoid accidentally decreasing quota too quickly. Setting the force\nparameter to true ignores this restriction.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "The resource name of the override to delete.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/adminOverrides/4a3f2c1d`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+/adminOverrides/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.list":

type ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall struct {
	s            *APIService
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all admin overrides on this limit.
func (r *ServicesConsumerQuotaMetricsLimitsAdminOverridesService) List(parent string) *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall {
	c := &ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Requested size of
// the next page of data.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) PageSize(pageSize int64) *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token identifying
// which result to start with; returned by a previous list
// call.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) PageToken(pageToken string) *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall {
	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 *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall {
	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 *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) IfNoneMatch(entityTag string) *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall {
	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 *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+parent}/adminOverrides")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.list" call.
// Exactly one of *ListAdminOverridesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListAdminOverridesResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) Do(opts ...googleapi.CallOption) (*ListAdminOverridesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListAdminOverridesResponse{
		ServerResponse: googleapi.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 admin overrides on this limit.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/adminOverrides",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Requested size of the next page of data.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token identifying which result to start with; returned by a previous list\ncall.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The resource name of the parent quota limit, returned by a\nListConsumerQuotaMetrics or GetConsumerQuotaMetric call.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/adminOverrides",
	//   "response": {
	//     "$ref": "ListAdminOverridesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *ServicesConsumerQuotaMetricsLimitsAdminOverridesListCall) Pages(ctx context.Context, f func(*ListAdminOverridesResponse) 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 "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.patch":

type ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall struct {
	s             *APIService
	name          string
	quotaoverride *QuotaOverride
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Patch: Updates an admin override.
func (r *ServicesConsumerQuotaMetricsLimitsAdminOverridesService) Patch(name string, quotaoverride *QuotaOverride) *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall {
	c := &ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.quotaoverride = quotaoverride
	return c
}

// Force sets the optional parameter "force": Whether to force the
// update of the quota override.
// If updating an override would cause the effective quota for the
// consumer to
// decrease by more than 10 percent, the call is rejected, as a safety
// measure
// to avoid accidentally decreasing quota too quickly. Setting the
// force
// parameter to true ignores this restriction.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall) Force(force bool) *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// UpdateMask sets the optional parameter "updateMask": Update only the
// specified fields of the override.
// If unset, all fields will be updated.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall) UpdateMask(updateMask string) *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.quotaoverride)
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.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 *ServicesConsumerQuotaMetricsLimitsAdminOverridesPatchCall) 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 admin override.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/adminOverrides/{adminOverridesId}",
	//   "httpMethod": "PATCH",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.adminOverrides.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "force": {
	//       "description": "Whether to force the update of the quota override.\nIf updating an override would cause the effective quota for the consumer to\ndecrease by more than 10 percent, the call is rejected, as a safety measure\nto avoid accidentally decreasing quota too quickly. Setting the force\nparameter to true ignores this restriction.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "The resource name of the override to update.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/adminOverrides/4a3f2c1d`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+/adminOverrides/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Update only the specified fields of the override.\nIf unset, all fields will be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "request": {
	//     "$ref": "QuotaOverride"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.create":

type ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall struct {
	s             *APIService
	parent        string
	quotaoverride *QuotaOverride
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Create: Creates a consumer override.
// A consumer override is applied to the consumer on its own authority
// to
// limit its own quota usage. Consumer overrides cannot be used to grant
// more
// quota than would be allowed by admin overrides, producer overrides,
// or the
// default limit of the service.
func (r *ServicesConsumerQuotaMetricsLimitsConsumerOverridesService) Create(parent string, quotaoverride *QuotaOverride) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall {
	c := &ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.quotaoverride = quotaoverride
	return c
}

// Force sets the optional parameter "force": Whether to force the
// creation of the quota override.
// If creating an override would cause the effective quota for the
// consumer to
// decrease by more than 10 percent, the call is rejected, as a safety
// measure
// to avoid accidentally decreasing quota too quickly. Setting the
// force
// parameter to true ignores this restriction.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall) Force(force bool) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.quotaoverride)
	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, "v1beta1/{+parent}/consumerOverrides")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.create" 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 *ServicesConsumerQuotaMetricsLimitsConsumerOverridesCreateCall) 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 consumer override.\nA consumer override is applied to the consumer on its own authority to\nlimit its own quota usage. Consumer overrides cannot be used to grant more\nquota than would be allowed by admin overrides, producer overrides, or the\ndefault limit of the service.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/consumerOverrides",
	//   "httpMethod": "POST",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "force": {
	//       "description": "Whether to force the creation of the quota override.\nIf creating an override would cause the effective quota for the consumer to\ndecrease by more than 10 percent, the call is rejected, as a safety measure\nto avoid accidentally decreasing quota too quickly. Setting the force\nparameter to true ignores this restriction.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "The resource name of the parent quota limit, returned by a\nListConsumerQuotaMetrics or GetConsumerQuotaMetric call.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/consumerOverrides",
	//   "request": {
	//     "$ref": "QuotaOverride"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.delete":

type ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall struct {
	s          *APIService
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a consumer override.
func (r *ServicesConsumerQuotaMetricsLimitsConsumerOverridesService) Delete(name string) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall {
	c := &ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Force sets the optional parameter "force": Whether to force the
// deletion of the quota override.
// If deleting an override would cause the effective quota for the
// consumer to
// decrease by more than 10 percent, the call is rejected, as a safety
// measure
// to avoid accidentally decreasing quota too quickly. Setting the
// force
// parameter to true ignores this restriction.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall) Force(force bool) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.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 *ServicesConsumerQuotaMetricsLimitsConsumerOverridesDeleteCall) 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 consumer override.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/consumerOverrides/{consumerOverridesId}",
	//   "httpMethod": "DELETE",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "force": {
	//       "description": "Whether to force the deletion of the quota override.\nIf deleting an override would cause the effective quota for the consumer to\ndecrease by more than 10 percent, the call is rejected, as a safety measure\nto avoid accidentally decreasing quota too quickly. Setting the force\nparameter to true ignores this restriction.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "The resource name of the override to delete.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/consumerOverrides/4a3f2c1d`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+/consumerOverrides/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}

// method id "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.list":

type ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall struct {
	s            *APIService
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all consumer overrides on this limit.
func (r *ServicesConsumerQuotaMetricsLimitsConsumerOverridesService) List(parent string) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall {
	c := &ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Requested size of
// the next page of data.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) PageSize(pageSize int64) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token identifying
// which result to start with; returned by a previous list
// call.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) PageToken(pageToken string) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall {
	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 *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall {
	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 *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) IfNoneMatch(entityTag string) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall {
	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 *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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, "v1beta1/{+parent}/consumerOverrides")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.list" call.
// Exactly one of *ListConsumerOverridesResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListConsumerOverridesResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) Do(opts ...googleapi.CallOption) (*ListConsumerOverridesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListConsumerOverridesResponse{
		ServerResponse: googleapi.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 consumer overrides on this limit.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/consumerOverrides",
	//   "httpMethod": "GET",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Requested size of the next page of data.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token identifying which result to start with; returned by a previous list\ncall.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The resource name of the parent quota limit, returned by a\nListConsumerQuotaMetrics or GetConsumerQuotaMetric call.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/consumerOverrides",
	//   "response": {
	//     "$ref": "ListConsumerOverridesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *ServicesConsumerQuotaMetricsLimitsConsumerOverridesListCall) Pages(ctx context.Context, f func(*ListConsumerOverridesResponse) 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 "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.patch":

type ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall struct {
	s             *APIService
	name          string
	quotaoverride *QuotaOverride
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Patch: Updates a consumer override.
func (r *ServicesConsumerQuotaMetricsLimitsConsumerOverridesService) Patch(name string, quotaoverride *QuotaOverride) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall {
	c := &ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.quotaoverride = quotaoverride
	return c
}

// Force sets the optional parameter "force": Whether to force the
// update of the quota override.
// If updating an override would cause the effective quota for the
// consumer to
// decrease by more than 10 percent, the call is rejected, as a safety
// measure
// to avoid accidentally decreasing quota too quickly. Setting the
// force
// parameter to true ignores this restriction.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall) Force(force bool) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// UpdateMask sets the optional parameter "updateMask": Update only the
// specified fields of the override.
// If unset, all fields will be updated.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall) UpdateMask(updateMask string) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall) Fields(s ...googleapi.Field) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall) Context(ctx context.Context) *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200727")
	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.quotaoverride)
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.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 *ServicesConsumerQuotaMetricsLimitsConsumerOverridesPatchCall) 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 consumer override.",
	//   "flatPath": "v1beta1/{v1beta1Id}/{v1beta1Id1}/services/{servicesId}/consumerQuotaMetrics/{consumerQuotaMetricsId}/limits/{limitsId}/consumerOverrides/{consumerOverridesId}",
	//   "httpMethod": "PATCH",
	//   "id": "serviceusage.services.consumerQuotaMetrics.limits.consumerOverrides.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "force": {
	//       "description": "Whether to force the update of the quota override.\nIf updating an override would cause the effective quota for the consumer to\ndecrease by more than 10 percent, the call is rejected, as a safety measure\nto avoid accidentally decreasing quota too quickly. Setting the force\nparameter to true ignores this restriction.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "The resource name of the override to update.\n\nAn example name would be:\n`projects/123/services/compute.googleapis.com/consumerQuotaMetrics/compute.googleapis.com%2Fcpus/limits/%2Fproject%2Fregion/consumerOverrides/4a3f2c1d`",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/services/[^/]+/consumerQuotaMetrics/[^/]+/limits/[^/]+/consumerOverrides/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Update only the specified fields of the override.\nIf unset, all fields will be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "request": {
	//     "$ref": "QuotaOverride"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/service.management"
	//   ]
	// }

}
