// Copyright 2019 Google Inc. All rights reserved.
// 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 servicecontrol provides access to the Service Control API.
//
// See https://cloud.google.com/service-control/
//
// Usage example:
//
//   import "google.golang.org/api/servicecontrol/v1"
//   ...
//   servicecontrolService, err := servicecontrol.New(oauthHttpClient)
package servicecontrol // import "google.golang.org/api/servicecontrol/v1"

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

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
)

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

const apiId = "servicecontrol:v1"
const apiName = "servicecontrol"
const apiVersion = "v1"
const basePath = "https://servicecontrol.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"

	// Manage your Google Service Control data
	ServicecontrolScope = "https://www.googleapis.com/auth/servicecontrol"
)

func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Services = NewServicesService(s)
	return s, nil
}

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

	Services *ServicesService
}

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

func NewServicesService(s *Service) *ServicesService {
	rs := &ServicesService{s: s}
	return rs
}

type ServicesService struct {
	s *Service
}

type AllocateInfo struct {
	// UnusedArguments: A list of label keys that were unused by the server
	// in processing the
	// request. Thus, for similar requests repeated in a certain future
	// time
	// window, the caller can choose to ignore these labels in the
	// requests
	// to achieve better client-side cache hits and quota aggregation.
	UnusedArguments []string `json:"unusedArguments,omitempty"`

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

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

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

// AllocateQuotaRequest: Request message for the AllocateQuota method.
type AllocateQuotaRequest struct {
	// AllocateOperation: Operation that describes the quota allocation.
	AllocateOperation *QuotaOperation `json:"allocateOperation,omitempty"`

	// ServiceConfigId: Specifies which version of service configuration
	// should be used to process
	// the request. If unspecified or no matching version can be found, the
	// latest
	// one will be used.
	ServiceConfigId string `json:"serviceConfigId,omitempty"`

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

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

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

// AllocateQuotaResponse: Response message for the AllocateQuota method.
type AllocateQuotaResponse struct {
	// AllocateErrors: Indicates the decision of the allocate.
	AllocateErrors []*QuotaError `json:"allocateErrors,omitempty"`

	// AllocateInfo: WARNING: DO NOT use this field until this warning
	// message is removed.
	AllocateInfo *AllocateInfo `json:"allocateInfo,omitempty"`

	// OperationId: The same operation_id value used in the
	// AllocateQuotaRequest. Used for
	// logging and diagnostics purposes.
	OperationId string `json:"operationId,omitempty"`

	// QuotaMetrics: Quota metrics to indicate the result of allocation.
	// Depending on the
	// request, one or more of the following metrics will be included:
	//
	// 1. Per quota group or per quota metric incremental usage will be
	// specified
	// using the following delta metric :
	//   "serviceruntime.googleapis.com/api/consumer/quota_used_count"
	//
	// 2. The quota limit reached condition will be specified using the
	// following
	// boolean metric :
	//   "serviceruntime.googleapis.com/quota/exceeded"
	QuotaMetrics []*MetricValueSet `json:"quotaMetrics,omitempty"`

	// ServiceConfigId: ID of the actual config used to process the request.
	ServiceConfigId string `json:"serviceConfigId,omitempty"`

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

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

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

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

// AuditLog: Common audit log format for Google Cloud Platform API
// operations.
//
//
type AuditLog struct {
	// AuthenticationInfo: Authentication information.
	AuthenticationInfo *AuthenticationInfo `json:"authenticationInfo,omitempty"`

	// AuthorizationInfo: Authorization information. If there are
	// multiple
	// resources or permissions involved, then there is
	// one AuthorizationInfo element for each {resource, permission} tuple.
	AuthorizationInfo []*AuthorizationInfo `json:"authorizationInfo,omitempty"`

	// Metadata: Other service-specific data about the request, response,
	// and other
	// information associated with the current audited event.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// MethodName: The name of the service method or operation.
	// For API calls, this should be the name of the API method.
	// For example,
	//
	//     "google.datastore.v1.Datastore.RunQuery"
	//     "google.logging.v1.LoggingService.DeleteLog"
	MethodName string `json:"methodName,omitempty"`

	// NumResponseItems: The number of items returned from a List or Query
	// API method,
	// if applicable.
	NumResponseItems int64 `json:"numResponseItems,omitempty,string"`

	// Request: The operation request. This may not include all request
	// parameters,
	// such as those that are too large, privacy-sensitive, or
	// duplicated
	// elsewhere in the log record.
	// It should never include user-generated data, such as file
	// contents.
	// When the JSON object represented here has a proto equivalent, the
	// proto
	// name will be indicated in the `@type` property.
	Request googleapi.RawMessage `json:"request,omitempty"`

	// RequestMetadata: Metadata about the operation.
	RequestMetadata *RequestMetadata `json:"requestMetadata,omitempty"`

	// ResourceLocation: The resource location information.
	ResourceLocation *ResourceLocation `json:"resourceLocation,omitempty"`

	// ResourceName: The resource or collection that is the target of the
	// operation.
	// The name is a scheme-less URI, not including the API service
	// name.
	// For example:
	//
	//     "shelves/SHELF_ID/books"
	//     "shelves/SHELF_ID/books/BOOK_ID"
	ResourceName string `json:"resourceName,omitempty"`

	// ResourceOriginalState: The resource's original state before mutation.
	// Present only for
	// operations which have successfully modified the targeted
	// resource(s).
	// In general, this field should contain all changed fields, except
	// those
	// that are already been included in `request`, `response`, `metadata`
	// or
	// `service_data` fields.
	// When the JSON object represented here has a proto equivalent,
	// the proto name will be indicated in the `@type` property.
	ResourceOriginalState googleapi.RawMessage `json:"resourceOriginalState,omitempty"`

	// Response: The operation response. This may not include all response
	// elements,
	// such as those that are too large, privacy-sensitive, or
	// duplicated
	// elsewhere in the log record.
	// It should never include user-generated data, such as file
	// contents.
	// When the JSON object represented here has a proto equivalent, the
	// proto
	// name will be indicated in the `@type` property.
	Response googleapi.RawMessage `json:"response,omitempty"`

	// ServiceData: Deprecated, use `metadata` field instead.
	// Other service-specific data about the request, response, and
	// other
	// activities.
	ServiceData googleapi.RawMessage `json:"serviceData,omitempty"`

	// ServiceName: The name of the API service performing the operation.
	// For example,
	// "datastore.googleapis.com".
	ServiceName string `json:"serviceName,omitempty"`

	// Status: The status of the overall operation.
	Status *Status `json:"status,omitempty"`

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

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

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

// Auth: This message defines request authentication attributes.
// Terminology is
// based on the JSON Web Token (JWT) standard, but the terms
// also
// correlate to concepts in other standards.
type Auth struct {
	// AccessLevels: A list of access level resource names that allow
	// resources to be
	// accessed by authenticated requester. It is part of Secure GCP
	// processing
	// for the incoming request. An access level string has the
	// format:
	// "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/
	// {short_name}"
	//
	// Example:
	// "//accesscontextmanager.googleapis.com/accessP
	// olicies/MY_POLICY_ID/accessLevels/MY_LEVEL"
	AccessLevels []string `json:"accessLevels,omitempty"`

	// Audiences: The intended audience(s) for this authentication
	// information. Reflects
	// the audience (`aud`) claim within a JWT. The audience
	// value(s) depends on the `issuer`, but typically include one or more
	// of
	// the following pieces of information:
	//
	// *  The services intended to receive the credential such as
	//    ["pubsub.googleapis.com", "storage.googleapis.com"]
	// *  A set of service-based scopes. For example,
	//    ["https://www.googleapis.com/auth/cloud-platform"]
	// *  The client id of an app, such as the Firebase project id for JWTs
	//    from Firebase Auth.
	//
	// Consult the documentation for the credential issuer to determine
	// the
	// information provided.
	Audiences []string `json:"audiences,omitempty"`

	// Claims: Structured claims presented with the credential. JWTs
	// include
	// `{key: value}` pairs for standard and private claims. The
	// following
	// is a subset of the standard required and optional claims that
	// would
	// typically be presented for a Google-based JWT:
	//
	//    {'iss': 'accounts.google.com',
	//     'sub': '113289723416554971153',
	//     'aud': ['123456789012', 'pubsub.googleapis.com'],
	//     'azp': '123456789012.apps.googleusercontent.com',
	//     'email': 'jsmith@example.com',
	//     'iat': 1353601026,
	//     'exp': 1353604926}
	//
	// SAML assertions are similarly specified, but with an identity
	// provider
	// dependent structure.
	Claims googleapi.RawMessage `json:"claims,omitempty"`

	// Presenter: The authorized presenter of the credential. Reflects the
	// optional
	// Authorized Presenter (`azp`) claim within a JWT or the
	// OAuth client id. For example, a Google Cloud Platform client id
	// looks
	// as follows: "123456789012.apps.googleusercontent.com".
	Presenter string `json:"presenter,omitempty"`

	// Principal: The authenticated principal. Reflects the issuer (`iss`)
	// and subject
	// (`sub`) claims within a JWT. The issuer and subject should be
	// `/`
	// delimited, with `/` percent-encoded within the subject fragment.
	// For
	// Google accounts, the principal format
	// is:
	// "https://accounts.google.com/{id}"
	Principal string `json:"principal,omitempty"`

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

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

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

// AuthenticationInfo: Authentication information for the operation.
type AuthenticationInfo struct {
	// AuthoritySelector: The authority selector specified by the requestor,
	// if any.
	// It is not guaranteed that the principal was allowed to use this
	// authority.
	AuthoritySelector string `json:"authoritySelector,omitempty"`

	// PrincipalEmail: The email address of the authenticated user (or
	// service account on behalf
	// of third party principal) making the request. For privacy reasons,
	// the
	// principal email address is redacted for all read-only operations that
	// fail
	// with a "permission denied" error.
	PrincipalEmail string `json:"principalEmail,omitempty"`

	// ServiceAccountKeyName: The name of the service account key used to
	// create or exchange
	// credentials for authenticating the service account making the
	// request.
	// This is a scheme-less URI full resource name. For
	// example:
	//
	// "//iam.googleapis.com/projects/{PROJECT_ID}/serviceAccounts/
	// {ACCOUNT}/keys/{key}"
	ServiceAccountKeyName string `json:"serviceAccountKeyName,omitempty"`

	// ThirdPartyPrincipal: The third party identification (if any) of the
	// authenticated user making
	// the request.
	// When the JSON object represented here has a proto equivalent, the
	// proto
	// name will be indicated in the `@type` property.
	ThirdPartyPrincipal googleapi.RawMessage `json:"thirdPartyPrincipal,omitempty"`

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

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

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

// AuthorizationInfo: Authorization information for the operation.
type AuthorizationInfo struct {
	// Granted: Whether or not authorization for `resource` and
	// `permission`
	// was granted.
	Granted bool `json:"granted,omitempty"`

	// Permission: The required IAM permission.
	Permission string `json:"permission,omitempty"`

	// Resource: The resource being accessed, as a REST-style string. For
	// example:
	//
	//     bigquery.googleapis.com/projects/PROJECTID/datasets/DATASETID
	Resource string `json:"resource,omitempty"`

	// ResourceAttributes: Resource attributes used in IAM condition
	// evaluation. This field contains
	// resource attributes like resource type and resource name.
	//
	// To get the whole view of the attributes used in IAM
	// condition evaluation, the user must also look
	// into
	// `AuditLog.request_metadata.request_attributes`.
	ResourceAttributes *Resource `json:"resourceAttributes,omitempty"`

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

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

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

// CheckError: Defines the errors to be returned
// in
// google.api.servicecontrol.v1.CheckResponse.check_errors.
type CheckError struct {
	// Code: The error code.
	//
	// Possible values:
	//   "ERROR_CODE_UNSPECIFIED" - This is never used in `CheckResponse`.
	//   "NOT_FOUND" - The consumer's project id, network container, or
	// resource container was
	// not found. Same as google.rpc.Code.NOT_FOUND.
	//   "PERMISSION_DENIED" - The consumer doesn't have access to the
	// specified resource.
	// Same as google.rpc.Code.PERMISSION_DENIED.
	//   "RESOURCE_EXHAUSTED" - Quota check failed. Same as
	// google.rpc.Code.RESOURCE_EXHAUSTED.
	//   "BUDGET_EXCEEDED" - Budget check failed.
	//   "DENIAL_OF_SERVICE_DETECTED" - The consumer's request has been
	// flagged as a DoS attack.
	//   "LOAD_SHEDDING" - The consumer's request should be rejected in
	// order to protect the service
	// from being overloaded.
	//   "ABUSER_DETECTED" - The consumer has been flagged as an abuser.
	//   "SERVICE_NOT_ACTIVATED" - The consumer hasn't activated the
	// service.
	//   "VISIBILITY_DENIED" - The consumer cannot access the service due to
	// visibility configuration.
	//   "BILLING_DISABLED" - The consumer cannot access the service because
	// billing is disabled.
	//   "PROJECT_DELETED" - The consumer's project has been marked as
	// deleted (soft deletion).
	//   "PROJECT_INVALID" - The consumer's project number or id does not
	// represent a valid project.
	//   "CONSUMER_INVALID" - The input consumer info does not represent a
	// valid consumer folder or
	// organization.
	//   "IP_ADDRESS_BLOCKED" - The IP address of the consumer is invalid
	// for the specific consumer
	// project.
	//   "REFERER_BLOCKED" - The referer address of the consumer request is
	// invalid for the specific
	// consumer project.
	//   "CLIENT_APP_BLOCKED" - The client application of the consumer
	// request is invalid for the
	// specific consumer project.
	//   "API_TARGET_BLOCKED" - The API targeted by this request is invalid
	// for the specified consumer
	// project.
	//   "API_KEY_INVALID" - The consumer's API key is invalid.
	//   "API_KEY_EXPIRED" - The consumer's API Key has expired.
	//   "API_KEY_NOT_FOUND" - The consumer's API Key was not found in
	// config record.
	//   "SPATULA_HEADER_INVALID" - The consumer's spatula header is
	// invalid.
	//   "LOAS_ROLE_INVALID" - The consumer's LOAS role is invalid.
	//   "NO_LOAS_PROJECT" - The consumer's LOAS role has no associated
	// project.
	//   "LOAS_PROJECT_DISABLED" - The consumer's LOAS project is not
	// `ACTIVE` in LoquatV2.
	//   "SECURITY_POLICY_VIOLATED" - Request is not allowed as per security
	// policies defined in Org Policy.
	//   "INVALID_CREDENTIAL" - The credential in the request can not be
	// verified.
	//   "LOCATION_POLICY_VIOLATED" - Request is not allowed as per location
	// policies defined in Org Policy.
	//   "NAMESPACE_LOOKUP_UNAVAILABLE" - The backend server for looking up
	// project id/number is unavailable.
	//   "SERVICE_STATUS_UNAVAILABLE" - The backend server for checking
	// service status is unavailable.
	//   "BILLING_STATUS_UNAVAILABLE" - The backend server for checking
	// billing status is unavailable.
	//   "QUOTA_CHECK_UNAVAILABLE" - The backend server for checking quota
	// limits is unavailable.
	//   "LOAS_PROJECT_LOOKUP_UNAVAILABLE" - The Spanner for looking up LOAS
	// project is unavailable.
	//   "CLOUD_RESOURCE_MANAGER_BACKEND_UNAVAILABLE" - Cloud Resource
	// Manager backend server is unavailable.
	//   "SECURITY_POLICY_BACKEND_UNAVAILABLE" - NOTE: for customers in the
	// scope of Beta/GA of
	// https://cloud.google.com/vpc-service-controls, this error
	// is no longer returned. If the security backend is unavailable,
	// rpc
	// UNAVAILABLE status will be returned instead. It should be ignored
	// and
	// should not be used to reject client requests.
	//   "LOCATION_POLICY_BACKEND_UNAVAILABLE" - Backend server for
	// evaluating location policy is unavailable.
	Code string `json:"code,omitempty"`

	// Detail: Free-form text providing details on the error cause of the
	// error.
	Detail string `json:"detail,omitempty"`

	// Subject: Subject to whom this error applies. See the specific code
	// enum for more
	// details on this field. For example:
	//     - “project:<project-id or project-number>”
	//     - “folder:<folder-id>”
	//     - “organization:<organization-id>”
	Subject string `json:"subject,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 *CheckError) MarshalJSON() ([]byte, error) {
	type NoMethod CheckError
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CheckInfo: Contains additional information about the check operation.
type CheckInfo struct {
	// ConsumerInfo: Consumer info of this check.
	ConsumerInfo *ConsumerInfo `json:"consumerInfo,omitempty"`

	// UnusedArguments: A list of fields and label keys that are ignored by
	// the server.
	// The client doesn't need to send them for following requests to
	// improve
	// performance and allow better aggregation.
	UnusedArguments []string `json:"unusedArguments,omitempty"`

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

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

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

// CheckRequest: Request message for the Check method.
type CheckRequest struct {
	// Operation: The operation to be checked.
	Operation *Operation `json:"operation,omitempty"`

	// RequestProjectSettings: Requests the project settings to be returned
	// as part of the check response.
	RequestProjectSettings bool `json:"requestProjectSettings,omitempty"`

	// ServiceConfigId: Specifies which version of service configuration
	// should be used to process
	// the request.
	//
	// If unspecified or no matching version can be found, the
	// latest one will be used.
	ServiceConfigId string `json:"serviceConfigId,omitempty"`

	// SkipActivationCheck: Indicates if service activation check should be
	// skipped for this request.
	// Default behavior is to perform the check and apply relevant quota.
	SkipActivationCheck bool `json:"skipActivationCheck,omitempty"`

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

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

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

// CheckResponse: Response message for the Check method.
type CheckResponse struct {
	// CheckErrors: Indicate the decision of the check.
	//
	// If no check errors are present, the service should process the
	// operation.
	// Otherwise the service should use the list of errors to determine
	// the
	// appropriate action.
	CheckErrors []*CheckError `json:"checkErrors,omitempty"`

	// CheckInfo: Feedback data returned from the server during processing a
	// Check request.
	CheckInfo *CheckInfo `json:"checkInfo,omitempty"`

	// OperationId: The same operation_id value used in the
	// CheckRequest.
	// Used for logging and diagnostics purposes.
	OperationId string `json:"operationId,omitempty"`

	// QuotaInfo: Quota information for the check request associated with
	// this response.
	//
	QuotaInfo *QuotaInfo `json:"quotaInfo,omitempty"`

	// ServiceConfigId: The actual config id used to process the request.
	ServiceConfigId string `json:"serviceConfigId,omitempty"`

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

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

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

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

// ConsumerInfo: `ConsumerInfo` provides information about the consumer.
type ConsumerInfo struct {
	// ConsumerNumber: The consumer identity number, can be Google cloud
	// project number, folder
	// number or organization number e.g. 1234567890. A value of 0 indicates
	// no
	// consumer number is found.
	ConsumerNumber int64 `json:"consumerNumber,omitempty,string"`

	// ProjectNumber: The Google cloud project number, e.g. 1234567890. A
	// value of 0 indicates
	// no project number is found.
	//
	// NOTE: This field is deprecated after Chemist support flexible
	// consumer
	// id. New code should not depend on this field anymore.
	ProjectNumber int64 `json:"projectNumber,omitempty,string"`

	// Possible values:
	//   "CONSUMER_TYPE_UNSPECIFIED"
	//   "PROJECT"
	//   "FOLDER"
	//   "ORGANIZATION"
	Type string `json:"type,omitempty"`

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

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

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

// Distribution: Distribution represents a frequency distribution of
// double-valued sample
// points. It contains the size of the population of sample points
// plus
// additional optional information:
//
//   - the arithmetic mean of the samples
//   - the minimum and maximum of the samples
//   - the sum-squared-deviation of the samples, used to compute
// variance
//   - a histogram of the values of the sample points
type Distribution struct {
	// BucketCounts: The number of samples in each histogram bucket.
	// `bucket_counts` are
	// optional. If present, they must sum to the `count` value.
	//
	// The buckets are defined below in `bucket_option`. There are N
	// buckets.
	// `bucket_counts[0]` is the number of samples in the underflow
	// bucket.
	// `bucket_counts[1]` to `bucket_counts[N-1]` are the numbers of
	// samples
	// in each of the finite buckets. And `bucket_counts[N] is the number
	// of samples in the overflow bucket. See the comments of
	// `bucket_option`
	// below for more details.
	//
	// Any suffix of trailing zeros may be omitted.
	BucketCounts googleapi.Int64s `json:"bucketCounts,omitempty"`

	// Count: The total number of samples in the distribution. Must be >= 0.
	Count int64 `json:"count,omitempty,string"`

	// ExplicitBuckets: Buckets with arbitrary user-provided width.
	ExplicitBuckets *ExplicitBuckets `json:"explicitBuckets,omitempty"`

	// ExponentialBuckets: Buckets with exponentially growing width.
	ExponentialBuckets *ExponentialBuckets `json:"exponentialBuckets,omitempty"`

	// LinearBuckets: Buckets with constant width.
	LinearBuckets *LinearBuckets `json:"linearBuckets,omitempty"`

	// Maximum: The maximum of the population of values. Ignored if `count`
	// is zero.
	Maximum float64 `json:"maximum,omitempty"`

	// Mean: The arithmetic mean of the samples in the distribution. If
	// `count` is
	// zero then this field must be zero.
	Mean float64 `json:"mean,omitempty"`

	// Minimum: The minimum of the population of values. Ignored if `count`
	// is zero.
	Minimum float64 `json:"minimum,omitempty"`

	// SumOfSquaredDeviation: The sum of squared deviations from the mean:
	//   Sum[i=1..count]((x_i - mean)^2)
	// where each x_i is a sample values. If `count` is zero then this
	// field
	// must be zero, otherwise validation of the request fails.
	SumOfSquaredDeviation float64 `json:"sumOfSquaredDeviation,omitempty"`

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

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

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

func (s *Distribution) UnmarshalJSON(data []byte) error {
	type NoMethod Distribution
	var s1 struct {
		Maximum               gensupport.JSONFloat64 `json:"maximum"`
		Mean                  gensupport.JSONFloat64 `json:"mean"`
		Minimum               gensupport.JSONFloat64 `json:"minimum"`
		SumOfSquaredDeviation gensupport.JSONFloat64 `json:"sumOfSquaredDeviation"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Maximum = float64(s1.Maximum)
	s.Mean = float64(s1.Mean)
	s.Minimum = float64(s1.Minimum)
	s.SumOfSquaredDeviation = float64(s1.SumOfSquaredDeviation)
	return nil
}

// ExplicitBuckets: Describing buckets with arbitrary user-provided
// width.
type ExplicitBuckets struct {
	// Bounds: 'bound' is a list of strictly increasing boundaries
	// between
	// buckets. Note that a list of length N-1 defines N buckets because
	// of fenceposting. See comments on `bucket_options` for details.
	//
	// The i'th finite bucket covers the interval
	//   [bound[i-1], bound[i])
	// where i ranges from 1 to bound_size() - 1. Note that there are
	// no
	// finite buckets at all if 'bound' only contains a single element;
	// in
	// that special case the single bound defines the boundary between
	// the
	// underflow and overflow buckets.
	//
	// bucket number                   lower bound    upper bound
	//  i == 0 (underflow)              -inf           bound[i]
	//  0 < i < bound_size()            bound[i-1]     bound[i]
	//  i == bound_size() (overflow)    bound[i-1]     +inf
	Bounds []float64 `json:"bounds,omitempty"`

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

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

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

// ExponentialBuckets: Describing buckets with exponentially growing
// width.
type ExponentialBuckets struct {
	// GrowthFactor: The i'th exponential bucket covers the interval
	//   [scale * growth_factor^(i-1), scale * growth_factor^i)
	// where i ranges from 1 to num_finite_buckets inclusive.
	// Must be larger than 1.0.
	GrowthFactor float64 `json:"growthFactor,omitempty"`

	// NumFiniteBuckets: The number of finite buckets. With the underflow
	// and overflow buckets,
	// the total number of buckets is `num_finite_buckets` + 2.
	// See comments on `bucket_options` for details.
	NumFiniteBuckets int64 `json:"numFiniteBuckets,omitempty"`

	// Scale: The i'th exponential bucket covers the interval
	//   [scale * growth_factor^(i-1), scale * growth_factor^i)
	// where i ranges from 1 to num_finite_buckets inclusive.
	// Must be > 0.
	Scale float64 `json:"scale,omitempty"`

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

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

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

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

// HttpRequest: A common proto for logging HTTP requests. Only contains
// semantics
// defined by the HTTP specification. Product-specific
// logging
// information MUST be defined in a separate message.
type HttpRequest struct {
	// CacheFillBytes: The number of HTTP response bytes inserted into
	// cache. Set only when a
	// cache fill was attempted.
	CacheFillBytes int64 `json:"cacheFillBytes,omitempty,string"`

	// CacheHit: Whether or not an entity was served from cache
	// (with or without validation).
	CacheHit bool `json:"cacheHit,omitempty"`

	// CacheLookup: Whether or not a cache lookup was attempted.
	CacheLookup bool `json:"cacheLookup,omitempty"`

	// CacheValidatedWithOriginServer: Whether or not the response was
	// validated with the origin server before
	// being served from cache. This field is only meaningful if `cache_hit`
	// is
	// True.
	CacheValidatedWithOriginServer bool `json:"cacheValidatedWithOriginServer,omitempty"`

	// Latency: The request processing latency on the server, from the time
	// the request was
	// received until the response was sent.
	Latency string `json:"latency,omitempty"`

	// Protocol: Protocol used for the request. Examples: "HTTP/1.1",
	// "HTTP/2", "websocket"
	Protocol string `json:"protocol,omitempty"`

	// Referer: The referer URL of the request, as defined in
	// [HTTP/1.1 Header
	// Field
	// Definitions](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.h
	// tml).
	Referer string `json:"referer,omitempty"`

	// RemoteIp: The IP address (IPv4 or IPv6) of the client that issued the
	// HTTP
	// request. Examples: "192.168.1.1", "FE80::0202:B3FF:FE1E:8329".
	RemoteIp string `json:"remoteIp,omitempty"`

	// RequestMethod: The request method. Examples: "GET", "HEAD",
	// "PUT", "POST".
	RequestMethod string `json:"requestMethod,omitempty"`

	// RequestSize: The size of the HTTP request message in bytes, including
	// the request
	// headers and the request body.
	RequestSize int64 `json:"requestSize,omitempty,string"`

	// RequestUrl: The scheme (http, https), the host name, the path, and
	// the query
	// portion of the URL that was requested.
	// Example: "http://example.com/some/info?color=red".
	RequestUrl string `json:"requestUrl,omitempty"`

	// ResponseSize: The size of the HTTP response message sent back to the
	// client, in bytes,
	// including the response headers and the response body.
	ResponseSize int64 `json:"responseSize,omitempty,string"`

	// ServerIp: The IP address (IPv4 or IPv6) of the origin server that the
	// request was
	// sent to.
	ServerIp string `json:"serverIp,omitempty"`

	// Status: The response code indicating the status of the
	// response.
	// Examples: 200, 404.
	Status int64 `json:"status,omitempty"`

	// UserAgent: The user agent sent by the client. Example:
	// "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET
	// CLR 1.0.3705)".
	UserAgent string `json:"userAgent,omitempty"`

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

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

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

// LinearBuckets: Describing buckets with constant width.
type LinearBuckets struct {
	// NumFiniteBuckets: The number of finite buckets. With the underflow
	// and overflow buckets,
	// the total number of buckets is `num_finite_buckets` + 2.
	// See comments on `bucket_options` for details.
	NumFiniteBuckets int64 `json:"numFiniteBuckets,omitempty"`

	// Offset: The i'th linear bucket covers the interval
	//   [offset + (i-1) * width, offset + i * width)
	// where i ranges from 1 to num_finite_buckets, inclusive.
	Offset float64 `json:"offset,omitempty"`

	// Width: The i'th linear bucket covers the interval
	//   [offset + (i-1) * width, offset + i * width)
	// where i ranges from 1 to num_finite_buckets, inclusive.
	// Must be strictly positive.
	Width float64 `json:"width,omitempty"`

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

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

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

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

// LogEntry: An individual log entry.
type LogEntry struct {
	// HttpRequest: Optional. Information about the HTTP request associated
	// with this
	// log entry, if applicable.
	HttpRequest *HttpRequest `json:"httpRequest,omitempty"`

	// InsertId: A unique ID for the log entry used for deduplication. If
	// omitted,
	// the implementation will generate one based on operation_id.
	InsertId string `json:"insertId,omitempty"`

	// Labels: A set of user-defined (key, value) data that provides
	// additional
	// information about the log entry.
	Labels map[string]string `json:"labels,omitempty"`

	// Name: Required. The log to which this log entry belongs. Examples:
	// "syslog",
	// "book_log".
	Name string `json:"name,omitempty"`

	// Operation: Optional. Information about an operation associated with
	// the log entry, if
	// applicable.
	Operation *LogEntryOperation `json:"operation,omitempty"`

	// ProtoPayload: The log entry payload, represented as a protocol buffer
	// that is
	// expressed as a JSON object. The only accepted type currently
	// is
	// AuditLog.
	ProtoPayload googleapi.RawMessage `json:"protoPayload,omitempty"`

	// Severity: The severity of the log entry. The default value
	// is
	// `LogSeverity.DEFAULT`.
	//
	// Possible values:
	//   "DEFAULT" - (0) The log entry has no assigned severity level.
	//   "DEBUG" - (100) Debug or trace information.
	//   "INFO" - (200) Routine information, such as ongoing status or
	// performance.
	//   "NOTICE" - (300) Normal but significant events, such as start up,
	// shut down, or
	// a configuration change.
	//   "WARNING" - (400) Warning events might cause problems.
	//   "ERROR" - (500) Error events are likely to cause problems.
	//   "CRITICAL" - (600) Critical events cause more severe problems or
	// outages.
	//   "ALERT" - (700) A person must take an action immediately.
	//   "EMERGENCY" - (800) One or more systems are unusable.
	Severity string `json:"severity,omitempty"`

	// StructPayload: The log entry payload, represented as a structure
	// that
	// is expressed as a JSON object.
	StructPayload googleapi.RawMessage `json:"structPayload,omitempty"`

	// TextPayload: The log entry payload, represented as a Unicode string
	// (UTF-8).
	TextPayload string `json:"textPayload,omitempty"`

	// Timestamp: The time the event described by the log entry occurred.
	// If
	// omitted, defaults to operation start time.
	Timestamp string `json:"timestamp,omitempty"`

	// Trace: Optional. Resource name of the trace associated with the log
	// entry, if any.
	// If this field contains a relative resource name, you can assume the
	// name is
	// relative to `//tracing.googleapis.com`.
	// Example:
	// `projects/my-projectid/traces/06796866738c859f2f19b7cfb321482
	// 4`
	Trace string `json:"trace,omitempty"`

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

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

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

// LogEntryOperation: Additional information about a potentially
// long-running operation with which
// a log entry is associated.
type LogEntryOperation struct {
	// First: Optional. Set this to True if this is the first log entry in
	// the operation.
	First bool `json:"first,omitempty"`

	// Id: Optional. An arbitrary operation identifier. Log entries with
	// the
	// same identifier are assumed to be part of the same operation.
	Id string `json:"id,omitempty"`

	// Last: Optional. Set this to True if this is the last log entry in the
	// operation.
	Last bool `json:"last,omitempty"`

	// Producer: Optional. An arbitrary producer identifier. The combination
	// of
	// `id` and `producer` must be globally unique.  Examples for
	// `producer`:
	// "MyDivision.MyBigCompany.com",
	// "github.com/MyProject/MyApplication".
	Producer string `json:"producer,omitempty"`

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

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

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

// MetricValue: Represents a single metric value.
type MetricValue struct {
	// BoolValue: A boolean value.
	BoolValue *bool `json:"boolValue,omitempty"`

	// DistributionValue: A distribution value.
	DistributionValue *Distribution `json:"distributionValue,omitempty"`

	// DoubleValue: A double precision floating point value.
	DoubleValue *float64 `json:"doubleValue,omitempty"`

	// EndTime: The end of the time period over which this metric value's
	// measurement
	// applies.
	EndTime string `json:"endTime,omitempty"`

	// Int64Value: A signed 64-bit integer value.
	Int64Value *int64 `json:"int64Value,omitempty,string"`

	// Labels: The labels describing the metric value.
	// See comments on google.api.servicecontrol.v1.Operation.labels for
	// the overriding relationship.
	Labels map[string]string `json:"labels,omitempty"`

	// MoneyValue: A money value.
	MoneyValue *Money `json:"moneyValue,omitempty"`

	// StartTime: The start of the time period over which this metric
	// value's measurement
	// applies. The time period has different semantics for different
	// metric
	// types (cumulative, delta, and gauge). See the metric
	// definition
	// documentation in the service configuration for details.
	StartTime string `json:"startTime,omitempty"`

	// StringValue: A text string value.
	StringValue *string `json:"stringValue,omitempty"`

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

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

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

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

// MetricValueSet: Represents a set of metric values in the same
// metric.
// Each metric value in the set should have a unique combination of
// start time,
// end time, and label values.
type MetricValueSet struct {
	// MetricName: The metric name defined in the service configuration.
	MetricName string `json:"metricName,omitempty"`

	// MetricValues: The values in this metric.
	MetricValues []*MetricValue `json:"metricValues,omitempty"`

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

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

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

// Money: Represents an amount of money with its currency type.
type Money struct {
	// CurrencyCode: The 3-letter currency code defined in ISO 4217.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// Nanos: Number of nano (10^-9) units of the amount.
	// The value must be between -999,999,999 and +999,999,999 inclusive.
	// If `units` is positive, `nanos` must be positive or zero.
	// If `units` is zero, `nanos` can be positive, zero, or negative.
	// If `units` is negative, `nanos` must be negative or zero.
	// For example $-1.75 is represented as `units`=-1 and
	// `nanos`=-750,000,000.
	Nanos int64 `json:"nanos,omitempty"`

	// Units: The whole units of the amount.
	// For example if `currencyCode` is "USD", then 1 unit is one US
	// dollar.
	Units int64 `json:"units,omitempty,string"`

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

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

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

// Operation: Represents information regarding an operation.
type Operation struct {
	// ConsumerId: Identity of the consumer who is using the service.
	// This field should be filled in for the operations initiated by
	// a
	// consumer, but not for service-initiated operations that are
	// not related to a specific consumer.
	//
	// This can be in one of the following formats:
	//   project:<project_id>,
	//   project_number:<project_number>,
	//   api_key:<api_key>.
	ConsumerId string `json:"consumerId,omitempty"`

	// EndTime: End time of the operation.
	// Required when the operation is used in ServiceController.Report,
	// but optional when the operation is used in ServiceController.Check.
	EndTime string `json:"endTime,omitempty"`

	// Importance: DO NOT USE. This is an experimental field.
	//
	// Possible values:
	//   "LOW" - The API implementation may cache and aggregate the
	// data.
	// The data may be lost when rare and unexpected system failures occur.
	//   "HIGH" - The API implementation doesn't cache and aggregate the
	// data.
	// If the method returns successfully, it's guaranteed that the data
	// has
	// been persisted in durable storage.
	//   "DEBUG" - In addition to the behavior described in HIGH, DEBUG
	// enables
	// additional validation logic that is only useful during the
	// onboarding
	// process. This is only available to Google internal services and
	// the service must be whitelisted by chemist-dev@google.com in order
	// to use this level.
	Importance string `json:"importance,omitempty"`

	// Labels: Labels describing the operation. Only the following labels
	// are allowed:
	//
	// - Labels describing monitored resources as defined in
	//   the service configuration.
	// - Default labels of metric values. When specified, labels defined in
	// the
	//   metric value override these default.
	// - The following labels defined by Google Cloud Platform:
	//     - `cloud.googleapis.com/location` describing the location where
	// the
	//        operation happened,
	//     - `servicecontrol.googleapis.com/user_agent` describing the user
	// agent
	//        of the API request,
	//     - `servicecontrol.googleapis.com/service_agent` describing the
	// service
	//        used to handle the API request (e.g. ESP),
	//     - `servicecontrol.googleapis.com/platform` describing the
	// platform
	//        where the API is served, such as App Engine, Compute Engine,
	// or
	//        Kubernetes Engine.
	Labels map[string]string `json:"labels,omitempty"`

	// LogEntries: Represents information to be logged.
	LogEntries []*LogEntry `json:"logEntries,omitempty"`

	// MetricValueSets: Represents information about this operation. Each
	// MetricValueSet
	// corresponds to a metric defined in the service configuration.
	// The data type used in the MetricValueSet must agree with
	// the data type specified in the metric definition.
	//
	// Within a single operation, it is not allowed to have more than
	// one
	// MetricValue instances that have the same metric names and
	// identical
	// label value combinations. If a request has such duplicated
	// MetricValue
	// instances, the entire request is rejected with
	// an invalid argument error.
	MetricValueSets []*MetricValueSet `json:"metricValueSets,omitempty"`

	// OperationId: Identity of the operation. This must be unique within
	// the scope of the
	// service that generated the operation. If the service calls
	// Check() and Report() on the same operation, the two calls should
	// carry
	// the same id.
	//
	// UUID version 4 is recommended, though not required.
	// In scenarios where an operation is computed from existing
	// information
	// and an idempotent id is desirable for deduplication purpose, UUID
	// version 5
	// is recommended. See RFC 4122 for details.
	OperationId string `json:"operationId,omitempty"`

	// OperationName: Fully qualified name of the operation. Reserved for
	// future use.
	OperationName string `json:"operationName,omitempty"`

	// QuotaProperties: Represents the properties needed for quota check.
	// Applicable only if this
	// operation is for a quota check request. If this is not specified, no
	// quota
	// check will be performed.
	QuotaProperties *QuotaProperties `json:"quotaProperties,omitempty"`

	// ResourceContainer: DO NOT USE. This field is deprecated, use
	// "resources" field instead.
	// The resource name of the parent of a resource in the resource
	// hierarchy.
	//
	// This can be in one of the following formats:
	//     - “projects/<project-id or project-number>”
	//     - “folders/<folder-id>”
	//     - “organizations/<organization-id>”
	ResourceContainer string `json:"resourceContainer,omitempty"`

	// Resources: The resources that are involved in the operation.
	// The maximum supported number of entries in this field is 100.
	Resources []*ResourceInfo `json:"resources,omitempty"`

	// StartTime: Required. Start time of the operation.
	StartTime string `json:"startTime,omitempty"`

	// UserLabels: User defined labels for the resource that this operation
	// is associated
	// with. Only a combination of 1000 user labels per consumer project
	// are
	// allowed.
	UserLabels map[string]string `json:"userLabels,omitempty"`

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

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

// Peer: This message defines attributes for a node that handles a
// network request.
// The node can be either a service or an application that sends,
// forwards,
// or receives the request. Service peers should fill in the
// `service`,
// `principal`, and `labels` as appropriate.
type Peer struct {
	// Ip: The IP address of the peer.
	Ip string `json:"ip,omitempty"`

	// Labels: The labels associated with the peer.
	Labels map[string]string `json:"labels,omitempty"`

	// Port: The network port of the peer.
	Port int64 `json:"port,omitempty,string"`

	// Principal: The identity of this peer. Similar to
	// `Request.auth.principal`, but
	// relative to the peer instead of the request. For example, the
	// idenity associated with a load balancer that forwared the request.
	Principal string `json:"principal,omitempty"`

	// RegionCode: The CLDR country/region code associated with the above IP
	// address.
	// If the IP address is private, the `region_code` should reflect
	// the
	// physical location where this peer is running.
	RegionCode string `json:"regionCode,omitempty"`

	// Service: The canonical service name of the peer.
	//
	// NOTE: different systems may have different service naming schemes.
	Service string `json:"service,omitempty"`

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

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

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

// QuotaError: Represents error information for QuotaOperation.
type QuotaError struct {
	// Code: Error code.
	//
	// Possible values:
	//   "UNSPECIFIED" - This is never used.
	//   "RESOURCE_EXHAUSTED" - Quota allocation failed.
	// Same as google.rpc.Code.RESOURCE_EXHAUSTED.
	//   "OUT_OF_RANGE" - Quota release failed.  This error is ONLY returned
	// on a NORMAL release.
	// More formally:  if a user requests a release of 10 tokens, but only
	// 5 tokens were previously allocated, in a BEST_EFFORT release, this
	// will
	// be considered a success, 5 tokens will be released, and the result
	// will
	// be "Ok".  If this is done in NORMAL mode, no tokens will be
	// released,
	// and an OUT_OF_RANGE error will be returned.
	// Same as google.rpc.Code.OUT_OF_RANGE.
	//   "BILLING_NOT_ACTIVE" - Consumer cannot access the service because
	// the service requires active
	// billing.
	//   "PROJECT_DELETED" - Consumer's project has been marked as deleted
	// (soft deletion).
	//   "API_KEY_INVALID" - Specified API key is invalid.
	//   "API_KEY_EXPIRED" - Specified API Key has expired.
	//   "SPATULA_HEADER_INVALID" - Consumer's spatula header is invalid.
	//   "LOAS_ROLE_INVALID" - The consumer's LOAS role is invalid.
	//   "NO_LOAS_PROJECT" - The consumer's LOAS role has no associated
	// project.
	//   "PROJECT_STATUS_UNAVAILABLE" - The backend server for looking up
	// project id/number is unavailable.
	//   "SERVICE_STATUS_UNAVAILABLE" - The backend server for checking
	// service status is unavailable.
	//   "BILLING_STATUS_UNAVAILABLE" - The backend server for checking
	// billing status is unavailable.
	//   "QUOTA_SYSTEM_UNAVAILABLE" - The backend server for checking quota
	// limits is unavailable.
	Code string `json:"code,omitempty"`

	// Description: Free-form text that provides details on the cause of the
	// error.
	Description string `json:"description,omitempty"`

	// Subject: Subject to whom this error applies. See the specific enum
	// for more details
	// on this field. For example, "clientip:<ip address of client>"
	// or
	// "project:<Google developer project id>".
	Subject string `json:"subject,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 *QuotaError) MarshalJSON() ([]byte, error) {
	type NoMethod QuotaError
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// QuotaInfo: Contains the quota information for a quota check response.
type QuotaInfo struct {
	// LimitExceeded: Quota Metrics that have exceeded quota limits.
	// For QuotaGroup-based quota, this is QuotaGroup.name
	// For QuotaLimit-based quota, this is QuotaLimit.name
	// See: google.api.Quota
	// Deprecated: Use quota_metrics to get per quota group limit exceeded
	// status.
	LimitExceeded []string `json:"limitExceeded,omitempty"`

	// QuotaConsumed: Map of quota group name to the actual number of tokens
	// consumed. If the
	// quota check was not successful, then this will not be populated due
	// to no
	// quota consumption.
	//
	// We are not merging this field with 'quota_metrics' field because of
	// the
	// complexity of scaling in Chemist client code base. For simplicity, we
	// will
	// keep this field for Castor (that scales quota usage) and
	// 'quota_metrics'
	// for SuperQuota (that doesn't scale quota usage).
	//
	QuotaConsumed map[string]int64 `json:"quotaConsumed,omitempty"`

	// QuotaMetrics: Quota metrics to indicate the usage. Depending on the
	// check request, one or
	// more of the following metrics will be included:
	//
	// 1. For rate quota, per quota group or per quota metric incremental
	// usage
	// will be specified using the following delta metric:
	//   "serviceruntime.googleapis.com/api/consumer/quota_used_count"
	//
	// 2. For allocation quota, per quota metric total usage will be
	// specified
	// using the following gauge metric:
	//
	// "serviceruntime.googleapis.com/allocation/consumer/quota_used_count"
	//
	//
	// 3. For both rate quota and allocation quota, the quota limit
	// reached
	// condition will be specified using the following boolean metric:
	//   "serviceruntime.googleapis.com/quota/exceeded"
	QuotaMetrics []*MetricValueSet `json:"quotaMetrics,omitempty"`

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

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

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

// QuotaOperation: Represents information regarding a quota operation.
type QuotaOperation struct {
	// ConsumerId: Identity of the consumer for whom this quota operation is
	// being performed.
	//
	// This can be in one of the following formats:
	//   project:<project_id>,
	//   project_number:<project_number>,
	//   api_key:<api_key>.
	ConsumerId string `json:"consumerId,omitempty"`

	// Labels: Labels describing the operation.
	Labels map[string]string `json:"labels,omitempty"`

	// MethodName: Fully qualified name of the API method for which this
	// quota operation is
	// requested. This name is used for matching quota rules or metric rules
	// and
	// billing status rules defined in service configuration.
	//
	// This field should not be set if any of the following is true:
	// (1) the quota operation is performed on non-API resources.
	// (2) quota_metrics is set because the caller is doing quota
	// override.
	//
	// Example of an RPC method name:
	//     google.example.library.v1.LibraryService.CreateShelf
	MethodName string `json:"methodName,omitempty"`

	// OperationId: Identity of the operation. This is expected to be unique
	// within the scope
	// of the service that generated the operation, and guarantees
	// idempotency in
	// case of retries.
	//
	// UUID version 4 is recommended, though not required. In scenarios
	// where an
	// operation is computed from existing information and an idempotent id
	// is
	// desirable for deduplication purpose, UUID version 5 is recommended.
	// See
	// RFC 4122 for details.
	OperationId string `json:"operationId,omitempty"`

	// QuotaMetrics: Represents information about this operation. Each
	// MetricValueSet
	// corresponds to a metric defined in the service configuration.
	// The data type used in the MetricValueSet must agree with
	// the data type specified in the metric definition.
	//
	// Within a single operation, it is not allowed to have more than
	// one
	// MetricValue instances that have the same metric names and
	// identical
	// label value combinations. If a request has such duplicated
	// MetricValue
	// instances, the entire request is rejected with
	// an invalid argument error.
	//
	// This field is mutually exclusive with method_name.
	QuotaMetrics []*MetricValueSet `json:"quotaMetrics,omitempty"`

	// QuotaMode: Quota mode for this operation.
	//
	// Possible values:
	//   "UNSPECIFIED" - Guard against implicit default. Must not be used.
	//   "NORMAL" - For AllocateQuota request, allocates quota for the
	// amount specified in
	// the service configuration or specified using the quota metrics. If
	// the
	// amount is higher than the available quota, allocation error will
	// be
	// returned and no quota will be allocated.
	// If multiple quotas are part of the request, and one fails, none of
	// the
	// quotas are allocated or released.
	//   "BEST_EFFORT" - The operation allocates quota for the amount
	// specified in the service
	// configuration or specified using the quota metrics. If the amount
	// is
	// higher than the available quota, request does not fail but all
	// available
	// quota will be allocated.
	//   "CHECK_ONLY" - For AllocateQuota request, only checks if there is
	// enough quota
	// available and does not change the available quota. No lock is placed
	// on
	// the available quota either.
	QuotaMode string `json:"quotaMode,omitempty"`

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

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

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

// QuotaProperties: Represents the properties needed for quota
// operations.
type QuotaProperties struct {
	// QuotaMode: Quota mode for this operation.
	//
	// Possible values:
	//   "ACQUIRE" - Decreases available quota by the cost specified for the
	// operation.
	// If cost is higher than available quota, operation fails and
	// returns
	// error.
	//   "ACQUIRE_BEST_EFFORT" - Decreases available quota by the cost
	// specified for the operation.
	// If cost is higher than available quota, operation does not fail
	// and
	// available quota goes down to zero but it returns error.
	//   "CHECK" - Does not change any available quota. Only checks if there
	// is enough
	// quota.
	// No lock is placed on the checked tokens neither.
	//   "RELEASE" - Increases available quota by the operation cost
	// specified for the
	// operation.
	QuotaMode string `json:"quotaMode,omitempty"`

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

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

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

// ReportError: Represents the processing error of one Operation in the
// request.
type ReportError struct {
	// OperationId: The Operation.operation_id value from the request.
	OperationId string `json:"operationId,omitempty"`

	// Status: Details of the error when processing the Operation.
	Status *Status `json:"status,omitempty"`

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

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

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

// ReportInfo: Contains additional info about the report operation.
type ReportInfo struct {
	// OperationId: The Operation.operation_id value from the request.
	OperationId string `json:"operationId,omitempty"`

	// QuotaInfo: Quota usage info when processing the `Operation`.
	QuotaInfo *QuotaInfo `json:"quotaInfo,omitempty"`

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

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

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

// ReportRequest: Request message for the Report method.
type ReportRequest struct {
	// Operations: Operations to be reported.
	//
	// Typically the service should report one operation per
	// request.
	// Putting multiple operations into a single request is allowed, but
	// should
	// be used only when multiple operations are natually available at the
	// time
	// of the report.
	//
	// If multiple operations are in a single request, the total request
	// size
	// should be no larger than 1MB. See ReportResponse.report_errors
	// for
	// partial failure behavior.
	Operations []*Operation `json:"operations,omitempty"`

	// ServiceConfigId: Specifies which version of service config should be
	// used to process the
	// request.
	//
	// If unspecified or no matching version can be found, the
	// latest one will be used.
	ServiceConfigId string `json:"serviceConfigId,omitempty"`

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

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

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

// ReportResponse: Response message for the Report method.
type ReportResponse struct {
	// ReportErrors: Partial failures, one for each `Operation` in the
	// request that failed
	// processing. There are three possible combinations of the RPC
	// status:
	//
	// 1. The combination of a successful RPC status and an empty
	// `report_errors`
	//    list indicates a complete success where all `Operations` in the
	//    request are processed successfully.
	// 2. The combination of a successful RPC status and a non-empty
	//    `report_errors` list indicates a partial success where some
	//    `Operations` in the request succeeded. Each
	//    `Operation` that failed processing has a corresponding item
	//    in this list.
	// 3. A failed RPC status indicates a general non-deterministic
	// failure.
	//    When this happens, it's impossible to know which of the
	//    'Operations' in the request succeeded or failed.
	ReportErrors []*ReportError `json:"reportErrors,omitempty"`

	// ReportInfos: Quota usage for each quota release `Operation`
	// request.
	//
	// Fully or partially failed quota release request may or may not be
	// present
	// in `report_quota_info`. For example, a failed quota release request
	// will
	// have the current quota usage info when precise quota library returns
	// the
	// info. A deadline exceeded quota request will not have quota usage
	// info.
	//
	// If there is no quota release request, report_quota_info will be
	// empty.
	//
	ReportInfos []*ReportInfo `json:"reportInfos,omitempty"`

	// ServiceConfigId: The actual config id used to process the request.
	ServiceConfigId string `json:"serviceConfigId,omitempty"`

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

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

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

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

// Request: This message defines attributes for an HTTP request. If the
// actual
// request is not an HTTP request, the runtime system should try to
// map
// the actual request to an equivalent HTTP request.
type Request struct {
	// Auth: The request authentication. May be absent for unauthenticated
	// requests.
	// Derived from the HTTP request `Authorization` header or equivalent.
	Auth *Auth `json:"auth,omitempty"`

	// Fragment: The HTTP URL fragment. No URL decoding is performed.
	Fragment string `json:"fragment,omitempty"`

	// Headers: The HTTP request headers. If multiple headers share the same
	// key, they
	// must be merged according to the HTTP spec. All header keys must
	// be
	// lowercased, because HTTP header keys are case-insensitive.
	Headers map[string]string `json:"headers,omitempty"`

	// Host: The HTTP request `Host` header value.
	Host string `json:"host,omitempty"`

	// Id: The unique ID for a request, which can be propagated to
	// downstream
	// systems. The ID should have low probability of collision
	// within a single day for a specific service.
	Id string `json:"id,omitempty"`

	// Method: The HTTP request method, such as `GET`, `POST`.
	Method string `json:"method,omitempty"`

	// Path: The HTTP URL path.
	Path string `json:"path,omitempty"`

	// Protocol: The network protocol used with the request, such as
	// "http/1.1",
	// "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic".
	// See
	// https://www.iana.org/assignments/tls-extensiontype-values/tls-exte
	// nsiontype-values.xhtml#alpn-protocol-ids
	// for details.
	Protocol string `json:"protocol,omitempty"`

	// Query: The HTTP URL query in the format of
	// `name1=value`&name2=value2`, as it
	// appears in the first line of the HTTP request. No decoding is
	// performed.
	Query string `json:"query,omitempty"`

	// Reason: A special parameter for request reason. It is used by
	// security systems
	// to associate auditing information with a request.
	Reason string `json:"reason,omitempty"`

	// Scheme: The HTTP URL scheme, such as `http` and `https`.
	Scheme string `json:"scheme,omitempty"`

	// Size: The HTTP request size in bytes. If unknown, it must be -1.
	Size int64 `json:"size,omitempty,string"`

	// Time: The timestamp when the `destination` service receives the first
	// byte of
	// the request.
	Time string `json:"time,omitempty"`

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

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

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

// RequestMetadata: Metadata about the request.
type RequestMetadata struct {
	// CallerIp: The IP address of the caller.
	// For caller from internet, this will be public IPv4 or IPv6
	// address.
	// For caller from a Compute Engine VM with external IP address,
	// this
	// will be the VM's external IP address. For caller from a
	// Compute
	// Engine VM without external IP address, if the VM is in the
	// same
	// organization (or project) as the accessed resource, `caller_ip`
	// will
	// be the VM's internal IPv4 address, otherwise the `caller_ip` will
	// be
	// redacted to "gce-internal-ip".
	// See https://cloud.google.com/compute/docs/vpc/ for more information.
	CallerIp string `json:"callerIp,omitempty"`

	// CallerNetwork: The network of the caller.
	// Set only if the network host project is part of the same GCP
	// organization
	// (or project) as the accessed resource.
	// See https://cloud.google.com/compute/docs/vpc/ for more
	// information.
	// This is a scheme-less URI full resource name. For example:
	//
	//
	// "//compute.googleapis.com/projects/PROJECT_ID/global/networks/NETWORK_
	// ID"
	CallerNetwork string `json:"callerNetwork,omitempty"`

	// CallerSuppliedUserAgent: The user agent of the caller.
	// This information is not authenticated and should be treated
	// accordingly.
	// For example:
	//
	// +   `google-api-python-client/1.4.0`:
	//     The request was made by the Google API client for Python.
	// +   `Cloud SDK Command Line Tool apitools-client/1.0 gcloud/0.9.62`:
	//     The request was made by the Google Cloud SDK CLI (gcloud).
	// +   `AppEngine-Google; (+http://code.google.com/appengine;
	// appid:
	// s~my-project`:
	//     The request was made from the `my-project` App Engine app.
	// NOLINT
	CallerSuppliedUserAgent string `json:"callerSuppliedUserAgent,omitempty"`

	// DestinationAttributes: The destination of a network activity, such as
	// accepting a TCP connection.
	// In a multi hop network activity, the destination represents the
	// receiver of
	// the last hop. Only two fields are used in this message, Peer.port
	// and
	// Peer.ip. These fields are optionally populated by those services
	// utilizing
	// the IAM condition feature.
	DestinationAttributes *Peer `json:"destinationAttributes,omitempty"`

	// RequestAttributes: Request attributes used in IAM condition
	// evaluation. This field contains
	// request attributes like request time and access levels associated
	// with
	// the request.
	//
	//
	// To get the whole view of the attributes used in IAM
	// condition evaluation, the user must also look
	// into
	// `AuditLog.authentication_info.resource_attributes`.
	RequestAttributes *Request `json:"requestAttributes,omitempty"`

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

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

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

// Resource: This message defines core attributes for a resource. A
// resource is an
// addressable (named) entity provided by the destination service.
// For
// example, a file stored on a network storage service.
type Resource struct {
	// Labels: The labels or tags on the resource, such as AWS resource tags
	// and
	// Kubernetes resource labels.
	Labels map[string]string `json:"labels,omitempty"`

	// Name: The stable identifier (name) of a resource on the `service`. A
	// resource
	// can be logically identified as
	// "//{resource.service}/{resource.name}".
	// The differences between a resource name and a URI are:
	//
	// *   Resource name is a logical identifier, independent of network
	//     protocol and API version. For example,
	//     `//pubsub.googleapis.com/projects/123/topics/news-feed`.
	// *   URI often includes protocol and version information, so it can
	//     be used directly by applications. For example,
	//
	// `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`.
	//
	// See
	//  https://cloud.google.com/apis/design/resource_names for details.
	Name string `json:"name,omitempty"`

	// Service: The name of the service that this resource belongs to, such
	// as
	// `pubsub.googleapis.com`. The service may be different from the
	// DNS
	// hostname that actually serves the request.
	Service string `json:"service,omitempty"`

	// Type: The type of the resource. The scheme is platform-specific
	// because
	// different platforms define their resources differently.
	Type string `json:"type,omitempty"`

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

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

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

// ResourceInfo: Describes a resource associated with this operation.
type ResourceInfo struct {
	// ResourceContainer: The identifier of the parent of this resource
	// instance.
	// Must be in one of the following formats:
	//     - “projects/<project-id or project-number>”
	//     - “folders/<folder-id>”
	//     - “organizations/<organization-id>”
	ResourceContainer string `json:"resourceContainer,omitempty"`

	// ResourceLocation: The location of the resource. If not empty, the
	// resource will be checked
	// against location policy. The value must be a valid zone, region
	// or
	// multiregion. For example: "europe-west4" or
	// "northamerica-northeast1-a"
	ResourceLocation string `json:"resourceLocation,omitempty"`

	// ResourceName: Name of the resource. This is used for auditing
	// purposes.
	ResourceName string `json:"resourceName,omitempty"`

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

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

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

// ResourceLocation: Location information about a resource.
type ResourceLocation struct {
	// CurrentLocations: The locations of a resource after the execution of
	// the operation.
	// Requests to create or delete a location based resource must
	// populate
	// the 'current_locations' field and not the 'original_locations'
	// field.
	// For example:
	//
	//     "europe-west1-a"
	//     "us-east1"
	//     "nam3"
	CurrentLocations []string `json:"currentLocations,omitempty"`

	// OriginalLocations: The locations of a resource prior to the execution
	// of the operation.
	// Requests that mutate the resource's location must populate both
	// the
	// 'original_locations' as well as the 'current_locations' fields.
	// For example:
	//
	//     "europe-west1-a"
	//     "us-east1"
	//     "nam3"
	OriginalLocations []string `json:"originalLocations,omitempty"`

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

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

func (s *ResourceLocation) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceLocation
	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). The error model is designed to
// be:
//
// - Simple to use and understand for most users
// - Flexible enough to meet unexpected needs
//
// # Overview
//
// The `Status` message contains three pieces of data: error code, error
// message,
// and error details. The error code should be an enum value
// of
// google.rpc.Code, but it may accept additional error codes if needed.
// The
// error message should be a developer-facing English message that
// helps
// developers *understand* and *resolve* the error. If a localized
// user-facing
// error message is needed, put the localized message in the error
// details or
// localize it in the client. The optional error details may contain
// arbitrary
// information about the error. There is a predefined set of error
// detail types
// in the package `google.rpc` that can be used for common error
// conditions.
//
// # Language mapping
//
// The `Status` message is the logical representation of the error
// model, but it
// is not necessarily the actual wire format. When the `Status` message
// is
// exposed in different client libraries and different wire protocols,
// it can be
// mapped differently. For example, it will likely be mapped to some
// exceptions
// in Java, but more likely mapped to some error codes in C.
//
// # Other uses
//
// The error model and the `Status` message can be used in a variety
// of
// environments, either with or without APIs, to provide a
// consistent developer experience across different
// environments.
//
// Example uses of this error model include:
//
// - Partial errors. If a service needs to return partial errors to the
// client,
//     it may embed the `Status` in the normal response to indicate the
// partial
//     errors.
//
// - Workflow errors. A typical workflow has multiple steps. Each step
// may
//     have a `Status` message for error reporting.
//
// - Batch operations. If a client uses batch request and batch
// response, the
//     `Status` message should be used directly inside batch response,
// one for
//     each error sub-response.
//
// - Asynchronous operations. If an API call embeds asynchronous
// operation
//     results in its response, the status of those operations should
// be
//     represented directly using the `Status` message.
//
// - Logging. If some API errors are stored in logs, the message
// `Status` could
//     be used directly after any stripping needed for security/privacy
// reasons.
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)
}

// method id "servicecontrol.services.allocateQuota":

type ServicesAllocateQuotaCall struct {
	s                    *Service
	serviceName          string
	allocatequotarequest *AllocateQuotaRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// AllocateQuota: Attempts to allocate quota for the specified consumer.
// It should be called
// before the operation is executed.
//
// This method requires the
// `servicemanagement.services.quota`
// permission on the specified service. For more information, see
// [Cloud IAM](https://cloud.google.com/iam).
//
// **NOTE:** The client **must** fail-open on server errors
// `INTERNAL`,
// `UNKNOWN`, `DEADLINE_EXCEEDED`, and `UNAVAILABLE`. To ensure
// system
// reliability, the server may inject these errors to prohibit any
// hard
// dependency on the quota functionality.
func (r *ServicesService) AllocateQuota(serviceName string, allocatequotarequest *AllocateQuotaRequest) *ServicesAllocateQuotaCall {
	c := &ServicesAllocateQuotaCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.serviceName = serviceName
	c.allocatequotarequest = allocatequotarequest
	return c
}

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

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

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

func (c *ServicesAllocateQuotaCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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.allocatequotarequest)
	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, "v1/services/{serviceName}:allocateQuota")
	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{
		"serviceName": c.serviceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "servicecontrol.services.allocateQuota" call.
// Exactly one of *AllocateQuotaResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AllocateQuotaResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesAllocateQuotaCall) Do(opts ...googleapi.CallOption) (*AllocateQuotaResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AllocateQuotaResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Attempts to allocate quota for the specified consumer. It should be called\nbefore the operation is executed.\n\nThis method requires the `servicemanagement.services.quota`\npermission on the specified service. For more information, see\n[Cloud IAM](https://cloud.google.com/iam).\n\n**NOTE:** The client **must** fail-open on server errors `INTERNAL`,\n`UNKNOWN`, `DEADLINE_EXCEEDED`, and `UNAVAILABLE`. To ensure system\nreliability, the server may inject these errors to prohibit any hard\ndependency on the quota functionality.",
	//   "flatPath": "v1/services/{serviceName}:allocateQuota",
	//   "httpMethod": "POST",
	//   "id": "servicecontrol.services.allocateQuota",
	//   "parameterOrder": [
	//     "serviceName"
	//   ],
	//   "parameters": {
	//     "serviceName": {
	//       "description": "Name of the service as specified in the service configuration. For example,\n`\"pubsub.googleapis.com\"`.\n\nSee google.api.Service for the definition of a service name.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/services/{serviceName}:allocateQuota",
	//   "request": {
	//     "$ref": "AllocateQuotaRequest"
	//   },
	//   "response": {
	//     "$ref": "AllocateQuotaResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/servicecontrol"
	//   ]
	// }

}

// method id "servicecontrol.services.check":

type ServicesCheckCall struct {
	s            *Service
	serviceName  string
	checkrequest *CheckRequest
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Check: Checks whether an operation on a service should be allowed to
// proceed
// based on the configuration of the service and related policies. It
// must be
// called before the operation is executed.
//
// If feasible, the client should cache the check results and reuse them
// for
// 60 seconds. In case of any server errors, the client should rely on
// the
// cached results for much longer time to avoid outage.
// WARNING: There is general 60s delay for the configuration and
// policy
// propagation, therefore callers MUST NOT depend on the `Check` method
// having
// the latest policy information.
//
// NOTE: the CheckRequest has the size limit of 64KB.
//
// This method requires the `servicemanagement.services.check`
// permission
// on the specified service. For more information, see
// [Cloud IAM](https://cloud.google.com/iam).
func (r *ServicesService) Check(serviceName string, checkrequest *CheckRequest) *ServicesCheckCall {
	c := &ServicesCheckCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.serviceName = serviceName
	c.checkrequest = checkrequest
	return c
}

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

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

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

func (c *ServicesCheckCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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.checkrequest)
	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, "v1/services/{serviceName}:check")
	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{
		"serviceName": c.serviceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "servicecontrol.services.check" call.
// Exactly one of *CheckResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CheckResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesCheckCall) Do(opts ...googleapi.CallOption) (*CheckResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CheckResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Checks whether an operation on a service should be allowed to proceed\nbased on the configuration of the service and related policies. It must be\ncalled before the operation is executed.\n\nIf feasible, the client should cache the check results and reuse them for\n60 seconds. In case of any server errors, the client should rely on the\ncached results for much longer time to avoid outage.\nWARNING: There is general 60s delay for the configuration and policy\npropagation, therefore callers MUST NOT depend on the `Check` method having\nthe latest policy information.\n\nNOTE: the CheckRequest has the size limit of 64KB.\n\nThis method requires the `servicemanagement.services.check` permission\non the specified service. For more information, see\n[Cloud IAM](https://cloud.google.com/iam).",
	//   "flatPath": "v1/services/{serviceName}:check",
	//   "httpMethod": "POST",
	//   "id": "servicecontrol.services.check",
	//   "parameterOrder": [
	//     "serviceName"
	//   ],
	//   "parameters": {
	//     "serviceName": {
	//       "description": "The service name as specified in its service configuration. For example,\n`\"pubsub.googleapis.com\"`.\n\nSee\n[google.api.Service](https://cloud.google.com/service-management/reference/rpc/google.api#google.api.Service)\nfor the definition of a service name.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/services/{serviceName}:check",
	//   "request": {
	//     "$ref": "CheckRequest"
	//   },
	//   "response": {
	//     "$ref": "CheckResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/servicecontrol"
	//   ]
	// }

}

// method id "servicecontrol.services.report":

type ServicesReportCall struct {
	s             *Service
	serviceName   string
	reportrequest *ReportRequest
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Report: Reports operation results to Google Service Control, such as
// logs and
// metrics. It should be called after an operation is completed.
//
// If feasible, the client should aggregate reporting data for up to
// 5
// seconds to reduce API traffic. Limiting aggregation to 5 seconds is
// to
// reduce data loss during client crashes. Clients should carefully
// choose
// the aggregation time window to avoid data loss risk more than
// 0.01%
// for business and compliance reasons.
//
// NOTE: the ReportRequest has the size limit of 1MB.
//
// This method requires the `servicemanagement.services.report`
// permission
// on the specified service. For more information, see
// [Google Cloud IAM](https://cloud.google.com/iam).
func (r *ServicesService) Report(serviceName string, reportrequest *ReportRequest) *ServicesReportCall {
	c := &ServicesReportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.serviceName = serviceName
	c.reportrequest = reportrequest
	return c
}

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

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

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

func (c *ServicesReportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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.reportrequest)
	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, "v1/services/{serviceName}:report")
	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{
		"serviceName": c.serviceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "servicecontrol.services.report" call.
// Exactly one of *ReportResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ReportResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesReportCall) Do(opts ...googleapi.CallOption) (*ReportResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ReportResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Reports operation results to Google Service Control, such as logs and\nmetrics. It should be called after an operation is completed.\n\nIf feasible, the client should aggregate reporting data for up to 5\nseconds to reduce API traffic. Limiting aggregation to 5 seconds is to\nreduce data loss during client crashes. Clients should carefully choose\nthe aggregation time window to avoid data loss risk more than 0.01%\nfor business and compliance reasons.\n\nNOTE: the ReportRequest has the size limit of 1MB.\n\nThis method requires the `servicemanagement.services.report` permission\non the specified service. For more information, see\n[Google Cloud IAM](https://cloud.google.com/iam).",
	//   "flatPath": "v1/services/{serviceName}:report",
	//   "httpMethod": "POST",
	//   "id": "servicecontrol.services.report",
	//   "parameterOrder": [
	//     "serviceName"
	//   ],
	//   "parameters": {
	//     "serviceName": {
	//       "description": "The service name as specified in its service configuration. For example,\n`\"pubsub.googleapis.com\"`.\n\nSee\n[google.api.Service](https://cloud.google.com/service-management/reference/rpc/google.api#google.api.Service)\nfor the definition of a service name.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/services/{serviceName}:report",
	//   "request": {
	//     "$ref": "ReportRequest"
	//   },
	//   "response": {
	//     "$ref": "ReportResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/servicecontrol"
	//   ]
	// }

}
