// Copyright 2018 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 serviceconsumermanagement provides access to the Service Consumer Management API.
//
// See https://cloud.google.com/service-consumer-management/docs/overview
//
// Usage example:
//
//   import "google.golang.org/api/serviceconsumermanagement/v1"
//   ...
//   serviceconsumermanagementService, err := serviceconsumermanagement.New(oauthHttpClient)
package serviceconsumermanagement // import "google.golang.org/api/serviceconsumermanagement/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 = "serviceconsumermanagement:v1"
const apiName = "serviceconsumermanagement"
const apiVersion = "v1"
const basePath = "https://serviceconsumermanagement.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"
)

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

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

	Operations *OperationsService

	Services *ServicesService
}

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

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

type OperationsService struct {
	s *APIService
}

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

type ServicesService struct {
	s *APIService

	TenancyUnits *ServicesTenancyUnitsService
}

func NewServicesTenancyUnitsService(s *APIService) *ServicesTenancyUnitsService {
	rs := &ServicesTenancyUnitsService{s: s}
	return rs
}

type ServicesTenancyUnitsService struct {
	s *APIService
}

// AddTenantProjectRequest: Request to add a newly created and
// configured tenant project to a tenancy
// unit.
type AddTenantProjectRequest struct {
	// ProjectConfig: Configuration of the new tenant project that will be
	// added to tenancy unit
	// resources.
	ProjectConfig *TenantProjectConfig `json:"projectConfig,omitempty"`

	// Tag: Tag of the added project. Must be less than 128 characters.
	// Required.
	Tag string `json:"tag,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

// ApplyTenantProjectConfigRequest: Request to apply configuration to an
// existing tenant project.
type ApplyTenantProjectConfigRequest struct {
	// ProjectConfig: Configuration that should be applied to the existing
	// tenant project.
	ProjectConfig *TenantProjectConfig `json:"projectConfig,omitempty"`

	// Tag: Tag of the project. Must be less than 128 characters. Required.
	Tag string `json:"tag,omitempty"`

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

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

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

// AttachTenantProjectRequest: Request to attach an existing project to
// the tenancy unit as a new tenant
// resource.
type AttachTenantProjectRequest struct {
	// ExternalResource: When attaching an external project, this is in the
	// format of
	// `projects/{project_number}’.
	ExternalResource string `json:"externalResource,omitempty"`

	// ReservedResource: When attaching a reserved project already in
	// Tenancy Units, this is the
	// tag of tenant resource under the tenancy unit for the service's
	// producer
	// project. The reserved tenant resource must be in active state.
	ReservedResource string `json:"reservedResource,omitempty"`

	// Tag: Tag of the tenant resource after attachment.
	// Must be less than 128 characters. Required.
	Tag string `json:"tag,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// AuthorizationConfig: Configuration of authorization.
//
// This section determines the authorization provider, if unspecified,
// then no
// authorization check will be done.
//
// Example:
//
//     experimental:
//       authorization:
//         provider: firebaserules.googleapis.com
type AuthorizationConfig struct {
	// Provider: The name of the authorization provider, such
	// as
	// firebaserules.googleapis.com.
	Provider string `json:"provider,omitempty"`

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

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

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

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

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

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

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

// BackendRule: A backend rule provides configuration for an individual
// API element.
type BackendRule struct {
	// Address: The address of the API backend.
	Address string `json:"address,omitempty"`

	// Deadline: The number of seconds to wait for a response from a
	// request.  The default
	// deadline for gRPC is infinite (no deadline) and HTTP requests is 5
	// seconds.
	Deadline float64 `json:"deadline,omitempty"`

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

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

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

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

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

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

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

// Billing: Billing related configuration of the service.
//
// The following example shows how to configure monitored resources and
// metrics
// for billing:
//
//     monitored_resources:
//     - type: library.googleapis.com/branch
//       labels:
//       - key: /city
//         description: The city where the library branch is located
// in.
//       - key: /name
//         description: The name of the branch.
//     metrics:
//     - name: library.googleapis.com/book/borrowed_count
//       metric_kind: DELTA
//       value_type: INT64
//     billing:
//       consumer_destinations:
//       - monitored_resource: library.googleapis.com/branch
//         metrics:
//         - library.googleapis.com/book/borrowed_count
type Billing struct {
	// ConsumerDestinations: Billing configurations for sending metrics to
	// the consumer project.
	// There can be multiple consumer destinations per service, each one
	// must have
	// a different monitored resource type. A metric can be used in at
	// most
	// one consumer destination.
	ConsumerDestinations []*BillingDestination `json:"consumerDestinations,omitempty"`

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

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

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

// BillingConfig: Describes billing configuration for a new tenant
// project.
type BillingConfig struct {
	// BillingAccount: Name of the billing account.
	// For example `billingAccounts/012345-567890-ABCDEF`.
	BillingAccount string `json:"billingAccount,omitempty"`

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

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

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

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

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

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

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

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

// CancelOperationRequest: The request message for
// Operations.CancelOperation.
type CancelOperationRequest struct {
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// CreateTenancyUnitRequest: Request to create a tenancy unit for a
// consumer of a service.
type CreateTenancyUnitRequest struct {
	// TenancyUnitId: Optional producer provided identifier of the tenancy
	// unit.
	// Must be no longer than 40 characters and preferably URI friendly.
	// If it is not provided, a UID for the tenancy unit will be auto
	// generated.
	// It must be unique across a service.
	// If the tenancy unit already exists for the service and consumer
	// pair,
	// `CreateTenancyUnit` will return the existing tenancy unit if the
	// provided
	// identifier is identical or empty, otherwise the call will fail.
	TenancyUnitId string `json:"tenancyUnitId,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Path: The path matched by this custom verb.
	Path string `json:"path,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Features: The list of features enabled on this endpoint.
	Features []string `json:"features,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Experimental: Experimental service configuration. These configuration
// options can
// only be used by whitelisted users.
type Experimental struct {
	// Authorization: Authorization configuration.
	Authorization *AuthorizationConfig `json:"authorization,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// ValueType: The type of data that can be assigned to the label.
	//
	// Possible values:
	//   "STRING" - A variable-length string. This is the default.
	//   "BOOL" - Boolean; true or false.
	//   "INT64" - A 64-bit signed integer.
	ValueType string `json:"valueType,omitempty"`

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

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

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

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

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

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

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

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

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

// ListTenancyUnitsResponse: Response for the list request.
type ListTenancyUnitsResponse struct {
	// NextPageToken: Pagination token for large results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TenancyUnits: Tenancy units matching the request.
	TenancyUnits []*TenancyUnit `json:"tenancyUnits,omitempty"`

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

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

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

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

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

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

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

	// Name: The name of the log. It must be less than 512 characters long
	// and can
	// include the following characters: upper- and lower-case
	// alphanumeric
	// characters [A-Za-z0-9], and punctuation characters including
	// slash, underscore, hyphen, period [/_-.].
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// MetricDescriptor: Defines a metric type and its schema. Once a metric
// descriptor is created,
// deleting or altering it stops data collection and makes the metric
// type's
// existing data unusable.
type MetricDescriptor struct {
	// Description: A detailed description of the metric, which can be used
	// in documentation.
	Description string `json:"description,omitempty"`

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

	// Labels: The set of labels that can be used to describe a
	// specific
	// instance of this metric type. For example,
	// the
	// `appengine.googleapis.com/http/server/response_latencies` metric
	// type has a label for the HTTP response code, `response_code`, so
	// you can look at latencies for successful responses or just
	// for responses that failed.
	Labels []*LabelDescriptor `json:"labels,omitempty"`

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

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

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

	// Type: The metric type, including its DNS name prefix. The type is
	// not
	// URL-encoded.  All user-defined metric types have the DNS
	// name
	// `custom.googleapis.com` or `external.googleapis.com`.  Metric types
	// should
	// use a natural hierarchical grouping. For example:
	//
	//     "custom.googleapis.com/invoice/paid/amount"
	//     "external.googleapis.com/prometheus/up"
	//     "appengine.googleapis.com/http/server/response_latencies"
	Type string `json:"type,omitempty"`

	// Unit: The unit in which the metric value is reported. It is only
	// applicable
	// if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`.
	// The
	// supported units are a subset of [The Unified Code for Units
	// of
	// Measure](http://unitsofmeasure.org/ucum.html) standard:
	//
	// **Basic units (UNIT)**
	//
	// * `bit`   bit
	// * `By`    byte
	// * `s`     second
	// * `min`   minute
	// * `h`     hour
	// * `d`     day
	//
	// **Prefixes (PREFIX)**
	//
	// * `k`     kilo    (10**3)
	// * `M`     mega    (10**6)
	// * `G`     giga    (10**9)
	// * `T`     tera    (10**12)
	// * `P`     peta    (10**15)
	// * `E`     exa     (10**18)
	// * `Z`     zetta   (10**21)
	// * `Y`     yotta   (10**24)
	// * `m`     milli   (10**-3)
	// * `u`     micro   (10**-6)
	// * `n`     nano    (10**-9)
	// * `p`     pico    (10**-12)
	// * `f`     femto   (10**-15)
	// * `a`     atto    (10**-18)
	// * `z`     zepto   (10**-21)
	// * `y`     yocto   (10**-24)
	// * `Ki`    kibi    (2**10)
	// * `Mi`    mebi    (2**20)
	// * `Gi`    gibi    (2**30)
	// * `Ti`    tebi    (2**40)
	//
	// **Grammar**
	//
	// The grammar also includes these connectors:
	//
	// * `/`    division (as an infix operator, e.g. `1/s`).
	// * `.`    multiplication (as an infix operator, e.g. `GBy.d`)
	//
	// The grammar for a unit is as follows:
	//
	//     Expression = Component { "." Component } { "/" Component } ;
	//
	//     Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ]
	//               | Annotation
	//               | "1"
	//               ;
	//
	//     Annotation = "{" NAME "}" ;
	//
	// Notes:
	//
	// * `Annotation` is just a comment if it follows a `UNIT` and is
	//    equivalent to `1` if it is used alone. For examples,
	//    `{requests}/s == 1/s`, `By{transmitted}/s == By/s`.
	// * `NAME` is a sequence of non-blank printable ASCII characters not
	//    containing '{' or '}'.
	// * `1` represents dimensionless value 1, such as in `1/s`.
	// * `%` represents dimensionless value 1/100, and annotates values
	// giving
	//    a percentage.
	Unit string `json:"unit,omitempty"`

	// ValueType: Whether the measurement is an integer, a floating-point
	// number, etc.
	// Some combinations of `metric_kind` and `value_type` might not be
	// supported.
	//
	// Possible values:
	//   "VALUE_TYPE_UNSPECIFIED" - Do not use this default value.
	//   "BOOL" - The value is a boolean.
	// This value type can be used only if the metric kind is `GAUGE`.
	//   "INT64" - The value is a signed 64-bit integer.
	//   "DOUBLE" - The value is a double precision floating point number.
	//   "STRING" - The value is a text string.
	// This value type can be used only if the metric kind is `GAUGE`.
	//   "DISTRIBUTION" - The value is a `Distribution`.
	//   "MONEY" - The value is money.
	ValueType string `json:"valueType,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Root: If non-empty specifies a path under which inherited HTTP
	// paths
	// are rooted.
	Root string `json:"root,omitempty"`

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

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

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

// MonitoredResourceDescriptor: An object that describes the schema of a
// MonitoredResource object using a
// type name and a set of labels.  For example, the monitored
// resource
// descriptor for Google Compute Engine VM instances has a type
// of
// "gce_instance" and specifies the use of the labels "instance_id"
// and
// "zone" to identify particular VM instances.
//
// Different APIs can support different monitored resource types. APIs
// generally
// provide a `list` method that returns the monitored resource
// descriptors used
// by the API.
type MonitoredResourceDescriptor struct {
	// Description: Optional. A detailed description of the monitored
	// resource type that might
	// be used in documentation.
	Description string `json:"description,omitempty"`

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

	// Labels: Required. A set of labels used to describe instances of this
	// monitored
	// resource type. For example, an individual Google Cloud SQL database
	// is
	// identified by values for the labels "database_id" and "zone".
	Labels []*LabelDescriptor `json:"labels,omitempty"`

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

	// Type: Required. The monitored resource type. For example, the
	// type
	// "cloudsql_database" represents databases in Google Cloud SQL.
	// The maximum length of this value is 256 characters.
	Type string `json:"type,omitempty"`

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

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

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

// Monitoring: Monitoring configuration of the service.
//
// The example below shows how to configure monitored resources and
// metrics
// for monitoring. In the example, a monitored resource and two metrics
// are
// defined. The `library.googleapis.com/book/returned_count` metric is
// sent
// to both producer and consumer projects, whereas
// the
// `library.googleapis.com/book/overdue_count` metric is only sent to
// the
// consumer project.
//
//     monitored_resources:
//     - type: library.googleapis.com/branch
//       labels:
//       - key: /city
//         description: The city where the library branch is located
// in.
//       - key: /name
//         description: The name of the branch.
//     metrics:
//     - name: library.googleapis.com/book/returned_count
//       metric_kind: DELTA
//       value_type: INT64
//       labels:
//       - key: /customer_id
//     - name: library.googleapis.com/book/overdue_count
//       metric_kind: GAUGE
//       value_type: INT64
//       labels:
//       - key: /customer_id
//     monitoring:
//       producer_destinations:
//       - monitored_resource: library.googleapis.com/branch
//         metrics:
//         - library.googleapis.com/book/returned_count
//       consumer_destinations:
//       - monitored_resource: library.googleapis.com/branch
//         metrics:
//         - library.googleapis.com/book/returned_count
//         - library.googleapis.com/book/overdue_count
type Monitoring struct {
	// ConsumerDestinations: Monitoring configurations for sending metrics
	// to the consumer project.
	// There can be multiple consumer destinations, each one must have
	// a
	// different monitored resource type. A metric can be used in at
	// most
	// one consumer destination.
	ConsumerDestinations []*MonitoringDestination `json:"consumerDestinations,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should have the format of `operations/some/unique/name`.
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

	// Value: The option's value packed in an Any message. If the value is a
	// primitive,
	// the corresponding wrapper type defined in
	// google/protobuf/wrappers.proto
	// should be used. If the value is an enum, it should be stored as an
	// int32
	// value using the google.protobuf.Int32Value type.
	Value googleapi.RawMessage `json:"value,omitempty"`

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

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

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

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

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

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

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

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

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

// PolicyBinding: Translates to IAM Policy bindings (without auditing at
// this level)
type PolicyBinding struct {
	// Members: Uses the same format as in IAM policy.
	// `member` must include both prefix and ID. For example,
	// `user:{emailId}`,
	// `serviceAccount:{emailId}`, `group:{emailId}`.
	Members []string `json:"members,omitempty"`

	// Role: Role.
	// (https://cloud.google.com/iam/docs/understanding-roles)
	// For example, `roles/viewer`, `roles/editor`, or `roles/owner`.
	Role string `json:"role,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

	// Duration: Duration of this limit in textual notation. Example:
	// "100s", "24h", "1d".
	// For duration longer than a day, only multiple of days is supported.
	// We
	// support only "100s" and "1d" for now. Additional support will be
	// added in
	// the future. "0" indicates indefinite duration.
	//
	// Used by group-based quotas only.
	Duration string `json:"duration,omitempty"`

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

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

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

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

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

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

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

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

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

// RemoveTenantProjectRequest: Request message to remove tenant project
// resource from the tenancy unit.
type RemoveTenantProjectRequest struct {
	// Tag: Tag of the resource within the tenancy unit.
	Tag string `json:"tag,omitempty"`

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

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

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

// SearchTenancyUnitsResponse: Response for the search query.
type SearchTenancyUnitsResponse struct {
	// NextPageToken: Pagination token for large results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TenancyUnits: Tenancy Units matching the request.
	TenancyUnits []*TenancyUnit `json:"tenancyUnits,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Experimental: Experimental configuration.
	Experimental *Experimental `json:"experimental,omitempty"`

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

	// Id: A unique ID for a specific instance of this message, typically
	// assigned
	// by the client for tracking purpose. If empty, the server may choose
	// to
	// generate one instead. Must be no longer than 60 characters.
	Id string `json:"id,omitempty"`

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

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

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

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

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

	// Name: The DNS address at which this service is available,
	// e.g. `calendar.googleapis.com`.
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

// ServiceAccountConfig: Describes service account configuration for the
// tenant project.
type ServiceAccountConfig struct {
	// AccountId: ID of the IAM service account to be created in tenant
	// project.
	// The email format of the service account will
	// be
	// "<account-id>@<tenant-project-id>.iam.gserviceaccount.com".
	// This account id has to be unique within tenant project and
	// producers
	// have to guarantee it. And it must be 6-30 characters long, and
	// matches the
	// regular expression `[a-z]([-a-z0-9]*[a-z0-9])`.
	AccountId string `json:"accountId,omitempty"`

	// TenantProjectRoles: Roles for the associated service account for the
	// tenant project.
	TenantProjectRoles []string `json:"tenantProjectRoles,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

// Status: The `Status` type defines a logical error model that is
// suitable for different
// programming environments, including REST APIs and RPC APIs. It is
// used by
// [gRPC](https://github.com/grpc). 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)
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// TenancyUnit: Representation of a tenancy unit.
type TenancyUnit struct {
	// Consumer: @OutputOnly Cloud resource name of the consumer of this
	// service.
	// For example 'projects/123456'.
	Consumer string `json:"consumer,omitempty"`

	// CreateTime: @OutputOnly The time this tenancy unit was created.
	CreateTime string `json:"createTime,omitempty"`

	// Name: Globally unique identifier of this tenancy
	// unit
	// "services/{service}/{collection id}/{resource
	// id}/tenancyUnits/{unit}"
	Name string `json:"name,omitempty"`

	// Service: @OutputOnly Google Cloud API name of the service owning this
	// tenancy unit.
	// For example 'serviceconsumermanagement.googleapis.com'.
	Service string `json:"service,omitempty"`

	// TenantResources: Resources constituting the tenancy unit.
	// There can be at most 512 tenant resources in a tenancy unit.
	TenantResources []*TenantResource `json:"tenantResources,omitempty"`

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

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

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

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

// TenantProjectConfig: This structure defines a tenant project to be
// added to the specified tenancy
// unit and its initial configuration and properties. A project lien
// will be
// created for the tenant project to prevent the tenant project from
// being
// deleted accidentally. The lien will be deleted as part of tenant
// project
// removal.
type TenantProjectConfig struct {
	// BillingConfig: Billing account properties.  Billing account must be
	// specified.
	BillingConfig *BillingConfig `json:"billingConfig,omitempty"`

	// Folder: Folder where project in this tenancy unit must be
	// located
	// This folder must have been previously created with proper
	// permissions for the caller to create and configure a project in
	// it.
	// Valid folder resource names have the format
	// `folders/{folder_number}`
	// (for example, `folders/123456`).
	Folder string `json:"folder,omitempty"`

	// Labels: Labels that will be applied to this project.
	Labels map[string]string `json:"labels,omitempty"`

	// ServiceAccountConfig: Configuration for IAM service account on tenant
	// project.
	ServiceAccountConfig *ServiceAccountConfig `json:"serviceAccountConfig,omitempty"`

	// Services: Google Cloud API names of services that will be activated
	// on this project
	// during provisioning.  If any of these services can not be
	// activated,
	// request will fail.
	// For example: 'compute.googleapis.com','cloudfunctions.googleapis.com'
	Services []string `json:"services,omitempty"`

	// TenantProjectPolicy: Describes ownership and policies for the new
	// tenant project. Required.
	TenantProjectPolicy *TenantProjectPolicy `json:"tenantProjectPolicy,omitempty"`

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

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

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

// TenantProjectPolicy: Describes policy settings that need to be
// applied to a newly
// created tenant project.
type TenantProjectPolicy struct {
	// PolicyBindings: Policy bindings to be applied to the tenant project,
	// in addition to the
	// 'roles/owner' role granted to the Service Consumer Management
	// service
	// account.
	// At least one binding must have the role `roles/owner`. Among the list
	// of
	// members for `roles/owner`, at least one of them must be either `user`
	// or
	// `group` type.
	PolicyBindings []*PolicyBinding `json:"policyBindings,omitempty"`

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

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

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

// TenantResource: Resource constituting the TenancyUnit.
type TenantResource struct {
	// Resource: @OutputOnly Identifier of the tenant resource.
	// For cloud projects, it is in the form 'projects/{number}'.
	// For example 'projects/123456'.
	Resource string `json:"resource,omitempty"`

	// Status: Status of tenant resource.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Unspecified status is the default unset
	// value.
	//   "PENDING_CREATE" - Creation of the tenant resource is ongoing.
	//   "ACTIVE" - Active resource.
	//   "PENDING_DELETE" - Deletion of the resource is ongoing.
	//   "FAILED" - Tenant resource creation or deletion has failed.
	Status string `json:"status,omitempty"`

	// Tag: Unique per single tenancy unit.
	Tag string `json:"tag,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// method id "serviceconsumermanagement.operations.cancel":

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

// Cancel: Starts asynchronous cancellation on a long-running operation.
//  The server
// makes a best effort to cancel the operation, but success is
// not
// guaranteed.  If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.  Clients can
// use
// Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether
// the
// operation completed despite cancellation. On successful
// cancellation,
// the operation is not deleted; instead, it becomes an operation
// with
// an Operation.error value with a google.rpc.Status.code of
// 1,
// corresponding to `Code.CANCELLED`.
func (r *OperationsService) Cancel(name string, canceloperationrequest *CancelOperationRequest) *OperationsCancelCall {
	c := &OperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.canceloperationrequest = canceloperationrequest
	return c
}

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

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

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

func (c *OperationsCancelCall) 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.canceloperationrequest)
	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/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.operations.cancel" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *OperationsCancelCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Starts asynchronous cancellation on a long-running operation.  The server\nmakes a best effort to cancel the operation, but success is not\nguaranteed.  If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.  Clients can use\nOperations.GetOperation or\nother methods to check whether the cancellation succeeded or whether the\noperation completed despite cancellation. On successful cancellation,\nthe operation is not deleted; instead, it becomes an operation with\nan Operation.error value with a google.rpc.Status.code of 1,\ncorresponding to `Code.CANCELLED`.",
	//   "flatPath": "v1/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "serviceconsumermanagement.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^operations/.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:cancel",
	//   "request": {
	//     "$ref": "CancelOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "serviceconsumermanagement.operations.delete":

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

// Delete: Deletes a long-running operation. This method indicates that
// the client is
// no longer interested in the operation result. It does not cancel
// the
// operation. If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.
func (r *OperationsService) Delete(name string) *OperationsDeleteCall {
	c := &OperationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

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

func (c *OperationsDeleteCall) 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
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.operations.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *OperationsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a long-running operation. This method indicates that the client is\nno longer interested in the operation result. It does not cancel the\noperation. If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.",
	//   "flatPath": "v1/operations/{operationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "serviceconsumermanagement.operations.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be deleted.",
	//       "location": "path",
	//       "pattern": "^operations/.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

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

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OperationsGetCall) IfNoneMatch(entityTag string) *OperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

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

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

func (c *OperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *OperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest state of a long-running operation.  Clients can use this\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "flatPath": "v1/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "serviceconsumermanagement.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

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

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

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

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

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OperationsListCall) IfNoneMatch(entityTag string) *OperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

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

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

func (c *OperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

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

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *OperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "serviceconsumermanagement.services.search":

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

// Search: Search tenancy units for a service.
func (r *ServicesService) Search(parent string) *ServicesSearchCall {
	c := &ServicesSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results returned by this request. Currently, the
// default maximum is set to 1000. If page_size is not provided or the
// size
// provided is a number larger than 1000, it will be automatically set
// to
// 1000.
func (c *ServicesSearchCall) PageSize(pageSize int64) *ServicesSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The continuation
// token, which is used to page through large result sets.
// To get the next page of results, set this parameter to the value
// of
// `nextPageToken` from the previous response.
func (c *ServicesSearchCall) PageToken(pageToken string) *ServicesSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": Set a query `{expression}`
// for querying tenancy units. Your `{expression}`
// must be in the format: `field_name=literal_string`. The `field_name`
// is the
// name of the field you want to compare. Supported fields
// are
// `tenant_resources.tag` and `tenant_resources.resource`.
//
// For example, to search tenancy units that contain at least one
// tenant
// resource with given tag 'xyz', use query
// `tenant_resources.tag=xyz`.
// To search tenancy units that contain at least one tenant resource
// with
// given resource name 'projects/123456', use
// query
// `tenant_resources.resource=projects/123456`.
//
// Multiple expressions can be joined with `AND`s. Tenancy units must
// match
// all expressions to be included in the result set. For
// example,
// `tenant_resources.tag=xyz AND
// tenant_resources.resource=projects/123456`
func (c *ServicesSearchCall) Query(query string) *ServicesSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ServicesSearchCall) IfNoneMatch(entityTag string) *ServicesSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

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

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

func (c *ServicesSearchCall) 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())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.search" call.
// Exactly one of *SearchTenancyUnitsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *SearchTenancyUnitsResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesSearchCall) Do(opts ...googleapi.CallOption) (*SearchTenancyUnitsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SearchTenancyUnitsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search tenancy units for a service.",
	//   "flatPath": "v1/services/{servicesId}:search",
	//   "httpMethod": "GET",
	//   "id": "serviceconsumermanagement.services.search",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of results returned by this request. Currently, the\ndefault maximum is set to 1000. If page_size is not provided or the size\nprovided is a number larger than 1000, it will be automatically set to\n1000.\n\nOptional.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The continuation token, which is used to page through large result sets.\nTo get the next page of results, set this parameter to the value of\n`nextPageToken` from the previous response.\n\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Service for which search is performed.\nservices/{service}\n{service} the name of a service, for example 'service.googleapis.com'.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "Set a query `{expression}` for querying tenancy units. Your `{expression}`\nmust be in the format: `field_name=literal_string`. The `field_name` is the\nname of the field you want to compare. Supported fields are\n`tenant_resources.tag` and `tenant_resources.resource`.\n\nFor example, to search tenancy units that contain at least one tenant\nresource with given tag 'xyz', use query `tenant_resources.tag=xyz`.\nTo search tenancy units that contain at least one tenant resource with\ngiven resource name 'projects/123456', use query\n`tenant_resources.resource=projects/123456`.\n\nMultiple expressions can be joined with `AND`s. Tenancy units must match\nall expressions to be included in the result set. For example,\n`tenant_resources.tag=xyz AND tenant_resources.resource=projects/123456`\n\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}:search",
	//   "response": {
	//     "$ref": "SearchTenancyUnitsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ServicesSearchCall) Pages(ctx context.Context, f func(*SearchTenancyUnitsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "serviceconsumermanagement.services.tenancyUnits.addProject":

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

// AddProject: Add a new tenant project to the tenancy unit.
// There can be at most 512 tenant projects in a tenancy unit.
// If there are previously failed `AddTenantProject` calls, you might
// need to
// call `RemoveTenantProject` first to clean them before you can make
// another
// `AddTenantProject` with the same tag.
// Operation<response: Empty>.
func (r *ServicesTenancyUnitsService) AddProject(parent string, addtenantprojectrequest *AddTenantProjectRequest) *ServicesTenancyUnitsAddProjectCall {
	c := &ServicesTenancyUnitsAddProjectCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.addtenantprojectrequest = addtenantprojectrequest
	return c
}

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

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

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

func (c *ServicesTenancyUnitsAddProjectCall) 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.addtenantprojectrequest)
	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/{+parent}:addProject")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.tenancyUnits.addProject" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ServicesTenancyUnitsAddProjectCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Add a new tenant project to the tenancy unit.\nThere can be at most 512 tenant projects in a tenancy unit.\nIf there are previously failed `AddTenantProject` calls, you might need to\ncall `RemoveTenantProject` first to clean them before you can make another\n`AddTenantProject` with the same tag.\nOperation\u003cresponse: Empty\u003e.",
	//   "flatPath": "v1/services/{servicesId}/{servicesId1}/{servicesId2}/tenancyUnits/{tenancyUnitsId}:addProject",
	//   "httpMethod": "POST",
	//   "id": "serviceconsumermanagement.services.tenancyUnits.addProject",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Name of the tenancy unit.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+/[^/]+/[^/]+/tenancyUnits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}:addProject",
	//   "request": {
	//     "$ref": "AddTenantProjectRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "serviceconsumermanagement.services.tenancyUnits.applyProjectConfig":

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

// ApplyProjectConfig: Apply configuration to an existing tenant
// project.
// This project must exist in active state and have the original
// owner
// account. Caller must have the permission to add a project to the
// given
// tenancy unit. Configuration will be applied, but any existing
// settings on
// the project will not be modified.
// Specified policy bindings will be applied. Existing binding will not
// be
// modified.
// Specified services will be activated.   No service will be
// deactivated.
// New billing configuration will be applied if specified.
// Omit billing configuration to keep the existing one.
// Service account in the project will be created if previously non
// existing.
// Operation fails if any of the steps fail, but no rollback of
// already
// applied configuration changes is attempted.
// Operation<response: Empty>.
func (r *ServicesTenancyUnitsService) ApplyProjectConfig(name string, applytenantprojectconfigrequest *ApplyTenantProjectConfigRequest) *ServicesTenancyUnitsApplyProjectConfigCall {
	c := &ServicesTenancyUnitsApplyProjectConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.applytenantprojectconfigrequest = applytenantprojectconfigrequest
	return c
}

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

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

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

func (c *ServicesTenancyUnitsApplyProjectConfigCall) 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.applytenantprojectconfigrequest)
	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/{+name}:applyProjectConfig")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.tenancyUnits.applyProjectConfig" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ServicesTenancyUnitsApplyProjectConfigCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Apply configuration to an existing tenant project.\nThis project must exist in active state and have the original owner\naccount. Caller must have the permission to add a project to the given\ntenancy unit. Configuration will be applied, but any existing settings on\nthe project will not be modified.\nSpecified policy bindings will be applied. Existing binding will not be\nmodified.\nSpecified services will be activated.   No service will be deactivated.\nNew billing configuration will be applied if specified.\nOmit billing configuration to keep the existing one.\nService account in the project will be created if previously non existing.\nOperation fails if any of the steps fail, but no rollback of already\napplied configuration changes is attempted.\nOperation\u003cresponse: Empty\u003e.",
	//   "flatPath": "v1/services/{servicesId}/{servicesId1}/{servicesId2}/tenancyUnits/{tenancyUnitsId}:applyProjectConfig",
	//   "httpMethod": "POST",
	//   "id": "serviceconsumermanagement.services.tenancyUnits.applyProjectConfig",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the tenancy unit.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+/[^/]+/[^/]+/tenancyUnits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:applyProjectConfig",
	//   "request": {
	//     "$ref": "ApplyTenantProjectConfigRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "serviceconsumermanagement.services.tenancyUnits.attachProject":

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

// AttachProject: Attach an existing project to the tenancy unit as a
// new tenant
// resource. The project could be either the tenant project reserved
// by
// calling AddTenantProject under tenancy unit for the producer project
// of
// service, or from outside.
// Caller will be checked against the permission as if
// calling
// AddTenantProject on the same consumer.
// To trigger the attachement, the targeted tenant project must be in
// a
// folder. Please also make sure ServiceConsumerManagement service
// account is
// the owner of that project. Note that these two requirements are
// already met
// if the project is reserved through
// AddTenantProject.
// Operation<response: Empty>.
func (r *ServicesTenancyUnitsService) AttachProject(name string, attachtenantprojectrequest *AttachTenantProjectRequest) *ServicesTenancyUnitsAttachProjectCall {
	c := &ServicesTenancyUnitsAttachProjectCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.attachtenantprojectrequest = attachtenantprojectrequest
	return c
}

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

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

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

func (c *ServicesTenancyUnitsAttachProjectCall) 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.attachtenantprojectrequest)
	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/{+name}:attachProject")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.tenancyUnits.attachProject" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ServicesTenancyUnitsAttachProjectCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Attach an existing project to the tenancy unit as a new tenant\nresource. The project could be either the tenant project reserved by\ncalling AddTenantProject under tenancy unit for the producer project of\nservice, or from outside.\nCaller will be checked against the permission as if calling\nAddTenantProject on the same consumer.\nTo trigger the attachement, the targeted tenant project must be in a\nfolder. Please also make sure ServiceConsumerManagement service account is\nthe owner of that project. Note that these two requirements are already met\nif the project is reserved through AddTenantProject.\nOperation\u003cresponse: Empty\u003e.",
	//   "flatPath": "v1/services/{servicesId}/{servicesId1}/{servicesId2}/tenancyUnits/{tenancyUnitsId}:attachProject",
	//   "httpMethod": "POST",
	//   "id": "serviceconsumermanagement.services.tenancyUnits.attachProject",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the tenancy unit that project will be attached to.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+/[^/]+/[^/]+/tenancyUnits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:attachProject",
	//   "request": {
	//     "$ref": "AttachTenantProjectRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "serviceconsumermanagement.services.tenancyUnits.create":

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

// Create: Creates a tenancy unit with no tenant resources.
func (r *ServicesTenancyUnitsService) Create(parent string, createtenancyunitrequest *CreateTenancyUnitRequest) *ServicesTenancyUnitsCreateCall {
	c := &ServicesTenancyUnitsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.createtenancyunitrequest = createtenancyunitrequest
	return c
}

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

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

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

func (c *ServicesTenancyUnitsCreateCall) 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.createtenancyunitrequest)
	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/{+parent}/tenancyUnits")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.tenancyUnits.create" call.
// Exactly one of *TenancyUnit or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TenancyUnit.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ServicesTenancyUnitsCreateCall) Do(opts ...googleapi.CallOption) (*TenancyUnit, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TenancyUnit{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a tenancy unit with no tenant resources.",
	//   "flatPath": "v1/services/{servicesId}/{servicesId1}/{servicesId2}/tenancyUnits",
	//   "httpMethod": "POST",
	//   "id": "serviceconsumermanagement.services.tenancyUnits.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "services/{service}/{collection id}/{resource id}\n{collection id} is the cloud resource collection type representing the\nservice consumer, for example 'projects', or 'organizations'.\n{resource id} is the consumer numeric id, such as project number: '123456'.\n{service} the name of a service, for example 'service.googleapis.com'.\nEnabled service binding using the new tenancy unit.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+/[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/tenancyUnits",
	//   "request": {
	//     "$ref": "CreateTenancyUnitRequest"
	//   },
	//   "response": {
	//     "$ref": "TenancyUnit"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "serviceconsumermanagement.services.tenancyUnits.delete":

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

// Delete: Delete a tenancy unit.  Before the tenancy unit is deleted,
// there should be
// no tenant resources in it.
// Operation<response: Empty>.
func (r *ServicesTenancyUnitsService) Delete(name string) *ServicesTenancyUnitsDeleteCall {
	c := &ServicesTenancyUnitsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

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

func (c *ServicesTenancyUnitsDeleteCall) 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
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.tenancyUnits.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ServicesTenancyUnitsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Delete a tenancy unit.  Before the tenancy unit is deleted, there should be\nno tenant resources in it.\nOperation\u003cresponse: Empty\u003e.",
	//   "flatPath": "v1/services/{servicesId}/{servicesId1}/{servicesId2}/tenancyUnits/{tenancyUnitsId}",
	//   "httpMethod": "DELETE",
	//   "id": "serviceconsumermanagement.services.tenancyUnits.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the tenancy unit to be deleted.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+/[^/]+/[^/]+/tenancyUnits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "serviceconsumermanagement.services.tenancyUnits.list":

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

// List: Find the tenancy unit for a service and consumer.
// This method should not be used in producers' runtime path, for
// example
// finding the tenant project number when creating VMs. Producers
// should
// persist the tenant project information after the project is created.
func (r *ServicesTenancyUnitsService) List(parent string) *ServicesTenancyUnitsListCall {
	c := &ServicesTenancyUnitsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filter expression over
// tenancy resources field.
func (c *ServicesTenancyUnitsListCall) Filter(filter string) *ServicesTenancyUnitsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results returned by this request.
func (c *ServicesTenancyUnitsListCall) PageSize(pageSize int64) *ServicesTenancyUnitsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The continuation
// token, which is used to page through large result sets.
// To get the next page of results, set this parameter to the value
// of
// `nextPageToken` from the previous response.
func (c *ServicesTenancyUnitsListCall) PageToken(pageToken string) *ServicesTenancyUnitsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ServicesTenancyUnitsListCall) IfNoneMatch(entityTag string) *ServicesTenancyUnitsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

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

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

func (c *ServicesTenancyUnitsListCall) 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())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/tenancyUnits")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.tenancyUnits.list" call.
// Exactly one of *ListTenancyUnitsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListTenancyUnitsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ServicesTenancyUnitsListCall) Do(opts ...googleapi.CallOption) (*ListTenancyUnitsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListTenancyUnitsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Find the tenancy unit for a service and consumer.\nThis method should not be used in producers' runtime path, for example\nfinding the tenant project number when creating VMs. Producers should\npersist the tenant project information after the project is created.",
	//   "flatPath": "v1/services/{servicesId}/{servicesId1}/{servicesId2}/tenancyUnits",
	//   "httpMethod": "GET",
	//   "id": "serviceconsumermanagement.services.tenancyUnits.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filter expression over tenancy resources field. Optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of results returned by this request.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The continuation token, which is used to page through large result sets.\nTo get the next page of results, set this parameter to the value of\n`nextPageToken` from the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Service and consumer. Required.\nservices/{service}/{collection id}/{resource id}\n{collection id} is the cloud resource collection type representing the\nservice consumer, for example 'projects', or 'organizations'.\n{resource id} is the consumer numeric id, such as project number: '123456'.\n{service} the name of a service, for example 'service.googleapis.com'.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+/[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/tenancyUnits",
	//   "response": {
	//     "$ref": "ListTenancyUnitsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ServicesTenancyUnitsListCall) Pages(ctx context.Context, f func(*ListTenancyUnitsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "serviceconsumermanagement.services.tenancyUnits.removeProject":

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

// RemoveProject: Removes specified project resource identified by
// tenant resource tag.
// It will remove project lien with 'TenantManager' origin if that was
// added.
// It will then attempt to delete the project.
// If that operation fails, this method fails.
// Operation<response: Empty>.
func (r *ServicesTenancyUnitsService) RemoveProject(name string, removetenantprojectrequest *RemoveTenantProjectRequest) *ServicesTenancyUnitsRemoveProjectCall {
	c := &ServicesTenancyUnitsRemoveProjectCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.removetenantprojectrequest = removetenantprojectrequest
	return c
}

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

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

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

func (c *ServicesTenancyUnitsRemoveProjectCall) 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.removetenantprojectrequest)
	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/{+name}:removeProject")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "serviceconsumermanagement.services.tenancyUnits.removeProject" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ServicesTenancyUnitsRemoveProjectCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Removes specified project resource identified by tenant resource tag.\nIt will remove project lien with 'TenantManager' origin if that was added.\nIt will then attempt to delete the project.\nIf that operation fails, this method fails.\nOperation\u003cresponse: Empty\u003e.",
	//   "flatPath": "v1/services/{servicesId}/{servicesId1}/{servicesId2}/tenancyUnits/{tenancyUnitsId}:removeProject",
	//   "httpMethod": "POST",
	//   "id": "serviceconsumermanagement.services.tenancyUnits.removeProject",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the tenancy unit.\nSuch as 'services/service.googleapis.com/projects/12345/tenancyUnits/abcd'.",
	//       "location": "path",
	//       "pattern": "^services/[^/]+/[^/]+/[^/]+/tenancyUnits/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:removeProject",
	//   "request": {
	//     "$ref": "RemoveTenantProjectRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
