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

// Code generated file. DO NOT EDIT.

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

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

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

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

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

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

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Feeds = NewFeedsService(s)
	s.Operations = NewOperationsService(s)
	s.V1 = NewV1Service(s)
	return s, nil
}

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

	Feeds *FeedsService

	Operations *OperationsService

	V1 *V1Service
}

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

func NewFeedsService(s *Service) *FeedsService {
	rs := &FeedsService{s: s}
	return rs
}

type FeedsService struct {
	s *Service
}

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

type OperationsService struct {
	s *Service
}

func NewV1Service(s *Service) *V1Service {
	rs := &V1Service{s: s}
	return rs
}

type V1Service struct {
	s *Service
}

// Asset: An asset in Google Cloud. An asset can be any resource in the
// Google
// Cloud
// [resource
// hierarchy](https://cloud.google.com/resource-manager/d
// ocs/cloud-platform-resource-hierarchy),
// a resource outside the Google Cloud resource hierarchy (such as
// Google
// Kubernetes Engine clusters and objects), or a Cloud IAM policy.
type Asset struct {
	AccessLevel *GoogleIdentityAccesscontextmanagerV1AccessLevel `json:"accessLevel,omitempty"`

	AccessPolicy *GoogleIdentityAccesscontextmanagerV1AccessPolicy `json:"accessPolicy,omitempty"`

	// Ancestors: The ancestry path of an asset in Google Cloud
	// [resource
	// hierarchy](https://cloud.google.com/resource-manager/docs/cl
	// oud-platform-resource-hierarchy),
	// represented as a list of relative resource names. An ancestry path
	// starts
	// with the closest ancestor in the hierarchy and ends at root. If the
	// asset
	// is a project, folder, or organization, the ancestry path starts from
	// the
	// asset itself.
	//
	// For example: `["projects/123456789", "folders/5432",
	// "organizations/1234"]`
	Ancestors []string `json:"ancestors,omitempty"`

	// AssetType: The type of the asset. For example:
	// "compute.googleapis.com/Disk"
	//
	// See [Supported
	// asset
	// types](https://cloud.google.com/asset-inventory/docs/supported-a
	// sset-types)
	// for more information.
	AssetType string `json:"assetType,omitempty"`

	// IamPolicy: A representation of the Cloud IAM policy set on a Google
	// Cloud resource.
	// There can be a maximum of one Cloud IAM policy set on any given
	// resource.
	// In addition, Cloud IAM policies inherit their granted access scope
	// from any
	// policies set on parent resources in the resource hierarchy.
	// Therefore, the
	// effectively policy is the union of both the policy set on this
	// resource
	// and each policy set on all of the resource's ancestry resource levels
	// in
	// the hierarchy. See
	// [this topic](https://cloud.google.com/iam/docs/policies#inheritance)
	// for
	// more information.
	IamPolicy *Policy `json:"iamPolicy,omitempty"`

	// Name: The full name of the asset. For
	// example:
	// "//compute.googleapis.com/projects/my_project_123/zones/zone1
	// /instances/instance1"
	//
	// See
	// [Resource
	// names](https://cloud.google.com/apis/design/resource_names#f
	// ull_resource_name)
	// for more information.
	Name string `json:"name,omitempty"`

	// OrgPolicy: A representation of an
	// [organization
	// policy](https://cloud.google.com/resource-manager/docs/o
	// rganization-policy/overview#organization_policy).
	// There can be more than one organization policy with different
	// constraints
	// set on a given resource.
	OrgPolicy []*GoogleCloudOrgpolicyV1Policy `json:"orgPolicy,omitempty"`

	// Resource: A representation of the resource.
	Resource *Resource `json:"resource,omitempty"`

	ServicePerimeter *GoogleIdentityAccesscontextmanagerV1ServicePerimeter `json:"servicePerimeter,omitempty"`

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

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

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

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

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

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

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

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

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

	// LogType: The log type that this config enables.
	//
	// Possible values:
	//   "LOG_TYPE_UNSPECIFIED" - Default case. Should never be this.
	//   "ADMIN_READ" - Admin reads. Example: CloudIAM getIamPolicy
	//   "DATA_WRITE" - Data writes. Example: CloudSQL Users create
	//   "DATA_READ" - Data reads. Example: CloudSQL Users list
	LogType string `json:"logType,omitempty"`

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

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

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

// BatchGetAssetsHistoryResponse: Batch get assets history response.
type BatchGetAssetsHistoryResponse struct {
	// Assets: A list of assets with valid time windows.
	Assets []*TemporalAsset `json:"assets,omitempty"`

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

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

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

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

// BigQueryDestination: A BigQuery destination.
type BigQueryDestination struct {
	// Dataset: Required. The BigQuery dataset in
	// format
	// "projects/projectId/datasets/datasetId", to which the snapshot
	// result
	// should be exported. If this dataset does not exist, the export call
	// returns
	// an error.
	Dataset string `json:"dataset,omitempty"`

	// Force: If the destination table already exists and this flag is
	// `TRUE`, the
	// table will be overwritten by the contents of assets snapshot. If the
	// flag
	// is not set and the destination table already exists, the export
	// call
	// returns an error.
	Force bool `json:"force,omitempty"`

	// Table: Required. The BigQuery table to which the snapshot result
	// should be
	// written. If this table does not exist, a new table with the given
	// name
	// will be created.
	Table string `json:"table,omitempty"`

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

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

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

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

	// Members: Specifies the identities requesting access for a Cloud
	// Platform resource.
	// `members` can have the following values:
	//
	// * `allUsers`: A special identifier that represents anyone who is
	//    on the internet; with or without a Google account.
	//
	// * `allAuthenticatedUsers`: A special identifier that represents
	// anyone
	//    who is authenticated with a Google account or a service
	// account.
	//
	// * `user:{emailid}`: An email address that represents a specific
	// Google
	//    account. For example, `alice@example.com` .
	//
	//
	// * `serviceAccount:{emailid}`: An email address that represents a
	// service
	//    account. For example,
	// `my-other-app@appspot.gserviceaccount.com`.
	//
	// * `group:{emailid}`: An email address that represents a Google
	// group.
	//    For example, `admins@example.com`.
	//
	// * `deleted:user:{emailid}?uid={uniqueid}`: An email address (plus
	// unique
	//    identifier) representing a user that has been recently deleted.
	// For
	//    example, `alice@example.com?uid=123456789012345678901`. If the
	// user is
	//    recovered, this value reverts to `user:{emailid}` and the
	// recovered user
	//    retains the role in the binding.
	//
	// * `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address
	// (plus
	//    unique identifier) representing a service account that has been
	// recently
	//    deleted. For example,
	//
	// `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`.
	//
	//    If the service account is undeleted, this value reverts to
	//    `serviceAccount:{emailid}` and the undeleted service account
	// retains the
	//    role in the binding.
	//
	// * `deleted:group:{emailid}?uid={uniqueid}`: An email address (plus
	// unique
	//    identifier) representing a Google group that has been recently
	//    deleted. For example,
	// `admins@example.com?uid=123456789012345678901`. If
	//    the group is recovered, this value reverts to `group:{emailid}`
	// and the
	//    recovered group retains the role in the binding.
	//
	//
	// * `domain:{domain}`: The G Suite domain (primary) that represents all
	// the
	//    users of that domain. For example, `google.com` or
	// `example.com`.
	//
	//
	Members []string `json:"members,omitempty"`

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

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

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

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

// CreateFeedRequest: Create asset feed request.
type CreateFeedRequest struct {
	// Feed: Required. The feed details. The field `name` must be empty and
	// it will be generated
	// in the format
	// of:
	// projects/project_number/feeds/feed_id
	// folders/folder_number/feeds/
	// feed_id
	// organizations/organization_number/feeds/feed_id
	Feed *Feed `json:"feed,omitempty"`

	// FeedId: Required. This is the client-assigned asset feed identifier
	// and it needs to
	// be unique under a specific parent project/folder/organization.
	FeedId string `json:"feedId,omitempty"`

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

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

func (s *CreateFeedRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateFeedRequest
	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:"-"`
}

// ExportAssetsRequest: Export asset request.
type ExportAssetsRequest struct {
	// AssetTypes: A list of asset types of which to take a snapshot for.
	// For example:
	// "compute.googleapis.com/Disk". If specified, only matching assets
	// will be
	// returned. See [Introduction to Cloud
	// Asset
	// Inventory](https://cloud.google.com/asset-inventory/docs/overvie
	// w)
	// for all supported asset types.
	AssetTypes []string `json:"assetTypes,omitempty"`

	// ContentType: Asset content type. If not specified, no content but the
	// asset name will be
	// returned.
	//
	// Possible values:
	//   "CONTENT_TYPE_UNSPECIFIED" - Unspecified content type.
	//   "RESOURCE" - Resource metadata.
	//   "IAM_POLICY" - The actual IAM policy set on a resource.
	//   "ORG_POLICY" - The Cloud Organization Policy set on an asset.
	//   "ACCESS_POLICY" - The Cloud Access context mananger Policy set on
	// an asset.
	ContentType string `json:"contentType,omitempty"`

	// OutputConfig: Required. Output configuration indicating where the
	// results will be output
	// to. All results will be in newline delimited JSON format.
	OutputConfig *OutputConfig `json:"outputConfig,omitempty"`

	// ReadTime: Timestamp to take an asset snapshot. This can only be set
	// to a timestamp
	// between the current time and the current time minus 35 days
	// (inclusive).
	// If not specified, the current time will be used. Due to delays in
	// resource
	// data collection and indexing, there is a volatile window during
	// which
	// running the same query may get different results.
	ReadTime string `json:"readTime,omitempty"`

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

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

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

// Expr: Represents a textual expression in the Common Expression
// Language (CEL)
// syntax. CEL is a C-like expression language. The syntax and semantics
// of CEL
// are documented at https://github.com/google/cel-spec.
//
// Example (Comparison):
//
//     title: "Summary size limit"
//     description: "Determines if a summary is less than 100 chars"
//     expression: "document.summary.size() < 100"
//
// Example (Equality):
//
//     title: "Requestor is owner"
//     description: "Determines if requestor is the document owner"
//     expression: "document.owner ==
// request.auth.claims.email"
//
// Example (Logic):
//
//     title: "Public documents"
//     description: "Determine whether the document should be publicly
// visible"
//     expression: "document.type != 'private' && document.type !=
// 'internal'"
//
// Example (Data Manipulation):
//
//     title: "Notification string"
//     description: "Create a notification string with a timestamp."
//     expression: "'New message received at ' +
// string(document.create_time)"
//
// The exact variables and functions that may be referenced within an
// expression
// are determined by the service that evaluates it. See the
// service
// documentation for additional information.
type Expr struct {
	// Description: Optional. Description of the expression. This is a
	// longer text which
	// describes the expression, e.g. when hovered over it in a UI.
	Description string `json:"description,omitempty"`

	// Expression: Textual representation of an expression in Common
	// Expression Language
	// syntax.
	Expression string `json:"expression,omitempty"`

	// Location: Optional. String indicating the location of the expression
	// for error
	// reporting, e.g. a file name and a position in the file.
	Location string `json:"location,omitempty"`

	// Title: Optional. Title for the expression, i.e. a short string
	// describing
	// its purpose. This can be used e.g. in UIs which allow to enter
	// the
	// expression.
	Title string `json:"title,omitempty"`

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

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

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

// Feed: An asset feed used to export asset updates to a
// destinations.
// An asset feed filter controls what updates are exported.
// The asset feed must be created within a project, organization,
// or
// folder. Supported destinations are:
// Cloud Pub/Sub topics.
type Feed struct {
	// AssetNames: A list of the full names of the assets to receive
	// updates. You must specify
	// either or both of asset_names and asset_types. Only asset updates
	// matching
	// specified asset_names and asset_types are exported to the feed.
	// For
	// example:
	// `//compute.googleapis.com/projects/my_project_123/zones/z
	// one1/instances/instance1`.
	// See
	// [Resource
	// Names](https://cloud.google.com/apis/design/resource_names#f
	// ull_resource_name)
	// for more info.
	AssetNames []string `json:"assetNames,omitempty"`

	// AssetTypes: A list of types of the assets to receive updates. You
	// must specify either
	// or both of asset_names and asset_types. Only asset updates
	// matching
	// specified asset_names and asset_types are exported to the feed.
	// For example: "compute.googleapis.com/Disk"
	//
	// See
	// [this
	// topic](https://cloud.google.com/asset-inventory/docs/supported-a
	// sset-types)
	// for a list of all supported asset types.
	AssetTypes []string `json:"assetTypes,omitempty"`

	// ContentType: Asset content type. If not specified, no content but the
	// asset name and
	// type will be returned.
	//
	// Possible values:
	//   "CONTENT_TYPE_UNSPECIFIED" - Unspecified content type.
	//   "RESOURCE" - Resource metadata.
	//   "IAM_POLICY" - The actual IAM policy set on a resource.
	//   "ORG_POLICY" - The Cloud Organization Policy set on an asset.
	//   "ACCESS_POLICY" - The Cloud Access context mananger Policy set on
	// an asset.
	ContentType string `json:"contentType,omitempty"`

	// FeedOutputConfig: Required. Feed output configuration defining where
	// the asset updates are
	// published to.
	FeedOutputConfig *FeedOutputConfig `json:"feedOutputConfig,omitempty"`

	// Name: Required. The format will
	// be
	// projects/{project_number}/feeds/{client-assigned_feed_identifier}
	// or
	// folders/{folder_number}/feeds/{client-assigned_feed_identifier}
	// or
	// organizations/{organization_number}/feeds/{client-assigned_feed_ide
	// ntifier}
	//
	// The client-assigned feed identifier must be unique within the
	// parent
	// project/folder/organization.
	Name string `json:"name,omitempty"`

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

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

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

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

// FeedOutputConfig: Output configuration for asset feed destination.
type FeedOutputConfig struct {
	// PubsubDestination: Destination on Cloud Pubsub.
	PubsubDestination *PubsubDestination `json:"pubsubDestination,omitempty"`

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

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

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

// GcsDestination: A Cloud Storage location.
type GcsDestination struct {
	// Uri: The uri of the Cloud Storage object. It's the same uri that is
	// used by
	// gsutil. For example: "gs://bucket_name/object_name". See [Viewing
	// and
	// Editing
	// Object
	// Metadata](https://cloud.google.com/storage/docs/viewing-editing
	// -metadata)
	// for more information.
	Uri string `json:"uri,omitempty"`

	// UriPrefix: The uri prefix of all generated Cloud Storage objects. For
	// example:
	// "gs://bucket_name/object_name_prefix". Each object uri is in
	// format:
	// "gs://bucket_name/object_name_prefix/<asset type>/<shard number> and
	// only
	// contains assets for that type. <shard number> starts from 0. For
	// example:
	// "gs://bucket_name/object_name_prefix/compute.googleapis.com/D
	// isk/0" is
	// the first shard of output objects containing
	// all
	// compute.googleapis.com/Disk assets. An INVALID_ARGUMENT error will
	// be
	// returned if file with the same name
	// "gs://bucket_name/object_name_prefix"
	// already exists.
	UriPrefix string `json:"uriPrefix,omitempty"`

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

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

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

// GoogleCloudOrgpolicyV1BooleanPolicy: Used in `policy_type` to specify
// how `boolean_policy` will behave at this
// resource.
type GoogleCloudOrgpolicyV1BooleanPolicy struct {
	// Enforced: If `true`, then the `Policy` is enforced. If `false`, then
	// any
	// configuration is acceptable.
	//
	// Suppose you have a
	// `Constraint`
	// `constraints/compute.disableSerialPortAccess` with
	// `constraint_default`
	// set to `ALLOW`. A `Policy` for that `Constraint` exhibits the
	// following
	// behavior:
	//   - If the `Policy` at this resource has enforced set to `false`,
	// serial
	//     port connection attempts will be allowed.
	//   - If the `Policy` at this resource has enforced set to `true`,
	// serial
	//     port connection attempts will be refused.
	//   - If the `Policy` at this resource is `RestoreDefault`, serial
	// port
	//     connection attempts will be allowed.
	//   - If no `Policy` is set at this resource or anywhere higher in the
	//     resource hierarchy, serial port connection attempts will be
	// allowed.
	//   - If no `Policy` is set at this resource, but one exists higher in
	// the
	//     resource hierarchy, the behavior is as if the`Policy` were set
	// at
	//     this resource.
	//
	// The following examples demonstrate the different possible
	// layerings:
	//
	// Example 1 (nearest `Constraint` wins):
	//   `organizations/foo` has a `Policy` with:
	//     {enforced: false}
	//   `projects/bar` has no `Policy` set.
	// The constraint at `projects/bar` and `organizations/foo` will not
	// be
	// enforced.
	//
	// Example 2 (enforcement gets replaced):
	//   `organizations/foo` has a `Policy` with:
	//     {enforced: false}
	//   `projects/bar` has a `Policy` with:
	//     {enforced: true}
	// The constraint at `organizations/foo` is not enforced.
	// The constraint at `projects/bar` is enforced.
	//
	// Example 3 (RestoreDefault):
	//   `organizations/foo` has a `Policy` with:
	//     {enforced: true}
	//   `projects/bar` has a `Policy` with:
	//     {RestoreDefault: {}}
	// The constraint at `organizations/foo` is enforced.
	// The constraint at `projects/bar` is not enforced,
	// because
	// `constraint_default` for the `Constraint` is `ALLOW`.
	Enforced bool `json:"enforced,omitempty"`

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

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

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

// GoogleCloudOrgpolicyV1ListPolicy: Used in `policy_type` to specify
// how `list_policy` behaves at this
// resource.
//
// `ListPolicy` can define specific values and subtrees of Cloud
// Resource
// Manager resource hierarchy (`Organizations`, `Folders`, `Projects`)
// that
// are allowed or denied by setting the `allowed_values` and
// `denied_values`
// fields. This is achieved by using the `under:` and optional `is:`
// prefixes.
// The `under:` prefix is used to denote resource subtree values.
// The `is:` prefix is used to denote specific values, and is required
// only
// if the value contains a ":". Values prefixed with "is:" are treated
// the
// same as values with no prefix.
// Ancestry subtrees must be in one of the following formats:
//     - "projects/<project-id>", e.g. "projects/tokyo-rain-123"
//     - "folders/<folder-id>", e.g. "folders/1234"
//     - "organizations/<organization-id>", e.g.
// "organizations/1234"
// The `supports_under` field of the associated `Constraint`  defines
// whether
// ancestry prefixes can be used. You can set `allowed_values`
// and
// `denied_values` in the same `Policy` if `all_values`
// is
// `ALL_VALUES_UNSPECIFIED`. `ALLOW` or `DENY` are used to allow or deny
// all
// values. If `all_values` is set to either `ALLOW` or
// `DENY`,
// `allowed_values` and `denied_values` must be unset.
type GoogleCloudOrgpolicyV1ListPolicy struct {
	// AllValues: The policy all_values state.
	//
	// Possible values:
	//   "ALL_VALUES_UNSPECIFIED" - Indicates that allowed_values or
	// denied_values must be set.
	//   "ALLOW" - A policy with this set allows all values.
	//   "DENY" - A policy with this set denies all values.
	AllValues string `json:"allValues,omitempty"`

	// AllowedValues: List of values allowed  at this resource. Can only be
	// set if `all_values`
	// is set to `ALL_VALUES_UNSPECIFIED`.
	AllowedValues []string `json:"allowedValues,omitempty"`

	// DeniedValues: List of values denied at this resource. Can only be set
	// if `all_values`
	// is set to `ALL_VALUES_UNSPECIFIED`.
	DeniedValues []string `json:"deniedValues,omitempty"`

	// InheritFromParent: Determines the inheritance behavior for this
	// `Policy`.
	//
	// By default, a `ListPolicy` set at a resource supercedes any `Policy`
	// set
	// anywhere up the resource hierarchy. However, if `inherit_from_parent`
	// is
	// set to `true`, then the values from the effective `Policy` of the
	// parent
	// resource are inherited, meaning the values set in this `Policy`
	// are
	// added to the values inherited up the hierarchy.
	//
	// Setting `Policy` hierarchies that inherit both allowed values and
	// denied
	// values isn't recommended in most circumstances to keep the
	// configuration
	// simple and understandable. However, it is possible to set a `Policy`
	// with
	// `allowed_values` set that inherits a `Policy` with `denied_values`
	// set.
	// In this case, the values that are allowed must be in `allowed_values`
	// and
	// not present in `denied_values`.
	//
	// For example, suppose you have a
	// `Constraint`
	// `constraints/serviceuser.services`, which has a `constraint_type`
	// of
	// `list_constraint`, and with `constraint_default` set to
	// `ALLOW`.
	// Suppose that at the Organization level, a `Policy` is applied
	// that
	// restricts the allowed API activations to {`E1`, `E2`}. Then, if
	// a
	// `Policy` is applied to a project below the Organization that
	// has
	// `inherit_from_parent` set to `false` and field all_values set to
	// DENY,
	// then an attempt to activate any API will be denied.
	//
	// The following examples demonstrate different possible layerings
	// for
	// `projects/bar` parented by `organizations/foo`:
	//
	// Example 1 (no inherited values):
	//   `organizations/foo` has a `Policy` with values:
	//     {allowed_values: "E1" allowed_values:"E2"}
	//   `projects/bar` has `inherit_from_parent` `false` and values:
	//     {allowed_values: "E3" allowed_values: "E4"}
	// The accepted values at `organizations/foo` are `E1`, `E2`.
	// The accepted values at `projects/bar` are `E3`, and `E4`.
	//
	// Example 2 (inherited values):
	//   `organizations/foo` has a `Policy` with values:
	//     {allowed_values: "E1" allowed_values:"E2"}
	//   `projects/bar` has a `Policy` with values:
	//     {value: "E3" value: "E4" inherit_from_parent: true}
	// The accepted values at `organizations/foo` are `E1`, `E2`.
	// The accepted values at `projects/bar` are `E1`, `E2`, `E3`, and
	// `E4`.
	//
	// Example 3 (inheriting both allowed and denied values):
	//   `organizations/foo` has a `Policy` with values:
	//     {allowed_values: "E1" allowed_values: "E2"}
	//   `projects/bar` has a `Policy` with:
	//     {denied_values: "E1"}
	// The accepted values at `organizations/foo` are `E1`, `E2`.
	// The value accepted at `projects/bar` is `E2`.
	//
	// Example 4 (RestoreDefault):
	//   `organizations/foo` has a `Policy` with values:
	//     {allowed_values: "E1" allowed_values:"E2"}
	//   `projects/bar` has a `Policy` with values:
	//     {RestoreDefault: {}}
	// The accepted values at `organizations/foo` are `E1`, `E2`.
	// The accepted values at `projects/bar` are either all or none
	// depending on
	// the value of `constraint_default` (if `ALLOW`, all; if
	// `DENY`, none).
	//
	// Example 5 (no policy inherits parent policy):
	//   `organizations/foo` has no `Policy` set.
	//   `projects/bar` has no `Policy` set.
	// The accepted values at both levels are either all or none depending
	// on
	// the value of `constraint_default` (if `ALLOW`, all; if
	// `DENY`, none).
	//
	// Example 6 (ListConstraint allowing all):
	//   `organizations/foo` has a `Policy` with values:
	//     {allowed_values: "E1" allowed_values: "E2"}
	//   `projects/bar` has a `Policy` with:
	//     {all: ALLOW}
	// The accepted values at `organizations/foo` are `E1`, E2`.
	// Any value is accepted at `projects/bar`.
	//
	// Example 7 (ListConstraint allowing none):
	//   `organizations/foo` has a `Policy` with values:
	//     {allowed_values: "E1" allowed_values: "E2"}
	//   `projects/bar` has a `Policy` with:
	//     {all: DENY}
	// The accepted values at `organizations/foo` are `E1`, E2`.
	// No value is accepted at `projects/bar`.
	//
	// Example 10 (allowed and denied subtrees of Resource Manager
	// hierarchy):
	// Given the following resource hierarchy
	//   O1->{F1, F2}; F1->{P1}; F2->{P2, P3},
	//   `organizations/foo` has a `Policy` with values:
	//     {allowed_values: "under:organizations/O1"}
	//   `projects/bar` has a `Policy` with:
	//     {allowed_values: "under:projects/P3"}
	//     {denied_values: "under:folders/F2"}
	// The accepted values at `organizations/foo` are `organizations/O1`,
	//   `folders/F1`, `folders/F2`, `projects/P1`, `projects/P2`,
	//   `projects/P3`.
	// The accepted values at `projects/bar` are `organizations/O1`,
	//   `folders/F1`, `projects/P1`.
	InheritFromParent bool `json:"inheritFromParent,omitempty"`

	// SuggestedValue: Optional. The Google Cloud Console will try to
	// default to a configuration
	// that matches the value specified in this `Policy`. If
	// `suggested_value`
	// is not set, it will inherit the value specified higher in the
	// hierarchy,
	// unless `inherit_from_parent` is `false`.
	SuggestedValue string `json:"suggestedValue,omitempty"`

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

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

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

// GoogleCloudOrgpolicyV1Policy: Defines a Cloud Organization `Policy`
// which is used to specify `Constraints`
// for configurations of Cloud Platform resources.
type GoogleCloudOrgpolicyV1Policy struct {
	// BooleanPolicy: For boolean `Constraints`, whether to enforce the
	// `Constraint` or not.
	BooleanPolicy *GoogleCloudOrgpolicyV1BooleanPolicy `json:"booleanPolicy,omitempty"`

	// Constraint: The name of the `Constraint` the `Policy` is configuring,
	// for example,
	// `constraints/serviceuser.services`.
	//
	// Immutable after creation.
	Constraint string `json:"constraint,omitempty"`

	// Etag: An opaque tag indicating the current version of the `Policy`,
	// used for
	// concurrency control.
	//
	// When the `Policy` is returned from either a `GetPolicy` or
	// a
	// `ListOrgPolicy` request, this `etag` indicates the version of the
	// current
	// `Policy` to use when executing a read-modify-write loop.
	//
	// When the `Policy` is returned from a `GetEffectivePolicy` request,
	// the
	// `etag` will be unset.
	//
	// When the `Policy` is used in a `SetOrgPolicy` method, use the `etag`
	// value
	// that was returned from a `GetOrgPolicy` request as part of
	// a
	// read-modify-write loop for concurrency control. Not setting the
	// `etag`in a
	// `SetOrgPolicy` request will result in an unconditional write of
	// the
	// `Policy`.
	Etag string `json:"etag,omitempty"`

	// ListPolicy: List of values either allowed or disallowed.
	ListPolicy *GoogleCloudOrgpolicyV1ListPolicy `json:"listPolicy,omitempty"`

	// RestoreDefault: Restores the default behavior of the constraint;
	// independent of
	// `Constraint` type.
	RestoreDefault *GoogleCloudOrgpolicyV1RestoreDefault `json:"restoreDefault,omitempty"`

	// UpdateTime: The time stamp the `Policy` was previously updated. This
	// is set by the
	// server, not specified by the caller, and represents the last time a
	// call to
	// `SetOrgPolicy` was made for that `Policy`. Any value set by the
	// client will
	// be ignored.
	UpdateTime string `json:"updateTime,omitempty"`

	// Version: Version of the `Policy`. Default version is 0;
	Version int64 `json:"version,omitempty"`

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

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

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

// GoogleCloudOrgpolicyV1RestoreDefault: Ignores policies set above this
// resource and restores the
// `constraint_default` enforcement behavior of the specific
// `Constraint` at
// this resource.
//
// Suppose that `constraint_default` is set to `ALLOW` for
// the
// `Constraint` `constraints/serviceuser.services`. Suppose that
// organization
// foo.com sets a `Policy` at their Organization resource node that
// restricts
// the allowed service activations to deny all service activations.
// They
// could then set a `Policy` with the `policy_type` `restore_default`
// on
// several experimental projects, restoring the
// `constraint_default`
// enforcement of the `Constraint` for only those projects, allowing
// those
// projects to have all services activated.
type GoogleCloudOrgpolicyV1RestoreDefault struct {
}

// GoogleIdentityAccesscontextmanagerV1AccessLevel: An `AccessLevel` is
// a label that can be applied to requests to Google Cloud
// services, along with a list of requirements necessary for the label
// to be
// applied.
type GoogleIdentityAccesscontextmanagerV1AccessLevel struct {
	// Basic: A `BasicLevel` composed of `Conditions`.
	Basic *GoogleIdentityAccesscontextmanagerV1BasicLevel `json:"basic,omitempty"`

	// CreateTime: Output only. Time the `AccessLevel` was created in UTC.
	CreateTime string `json:"createTime,omitempty"`

	// Custom: A `CustomLevel` written in the Common Expression Language.
	Custom *GoogleIdentityAccesscontextmanagerV1CustomLevel `json:"custom,omitempty"`

	// Description: Description of the `AccessLevel` and its use. Does not
	// affect behavior.
	Description string `json:"description,omitempty"`

	// Name: Required. Resource name for the Access Level. The `short_name`
	// component
	// must begin with a letter and only include alphanumeric and '_'.
	// Format:
	// `accessPolicies/{policy_id}/accessLevels/{short_name}`. The maximum
	// length
	// of the `short_name` component is 50 characters.
	Name string `json:"name,omitempty"`

	// Title: Human readable title. Must be unique within the Policy.
	Title string `json:"title,omitempty"`

	// UpdateTime: Output only. Time the `AccessLevel` was updated in UTC.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1AccessPolicy: `AccessPolicy` is a
// container for `AccessLevels` (which define the necessary
// attributes to use Google Cloud services) and `ServicePerimeters`
// (which
// define regions of services able to freely pass data within a
// perimeter). An
// access policy is globally visible within an organization, and
// the
// restrictions it specifies apply to all projects within an
// organization.
type GoogleIdentityAccesscontextmanagerV1AccessPolicy struct {
	// CreateTime: Output only. Time the `AccessPolicy` was created in UTC.
	CreateTime string `json:"createTime,omitempty"`

	// Etag: Output only. An opaque identifier for the current version of
	// the
	// `AccessPolicy`. This will always be a strongly validated etag,
	// meaning that
	// two Access Polices will be identical if and only if their etags
	// are
	// identical. Clients should not expect this to be in any specific
	// format.
	Etag string `json:"etag,omitempty"`

	// Name: Output only. Resource name of the `AccessPolicy`.
	// Format:
	// `accessPolicies/{policy_id}`
	Name string `json:"name,omitempty"`

	// Parent: Required. The parent of this `AccessPolicy` in the Cloud
	// Resource
	// Hierarchy. Currently immutable once created.
	// Format:
	// `organizations/{organization_id}`
	Parent string `json:"parent,omitempty"`

	// Title: Required. Human readable title. Does not affect behavior.
	Title string `json:"title,omitempty"`

	// UpdateTime: Output only. Time the `AccessPolicy` was updated in UTC.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1BasicLevel: `BasicLevel` is an
// `AccessLevel` using a set of recommended features.
type GoogleIdentityAccesscontextmanagerV1BasicLevel struct {
	// CombiningFunction: How the `conditions` list should be combined to
	// determine if a request is
	// granted this `AccessLevel`. If AND is used, each `Condition`
	// in
	// `conditions` must be satisfied for the `AccessLevel` to be applied.
	// If OR
	// is used, at least one `Condition` in `conditions` must be satisfied
	// for the
	// `AccessLevel` to be applied. Default behavior is AND.
	//
	// Possible values:
	//   "AND" - All `Conditions` must be true for the `BasicLevel` to be
	// true.
	//   "OR" - If at least one `Condition` is true, then the `BasicLevel`
	// is true.
	CombiningFunction string `json:"combiningFunction,omitempty"`

	// Conditions: Required. A list of requirements for the `AccessLevel` to
	// be granted.
	Conditions []*GoogleIdentityAccesscontextmanagerV1Condition `json:"conditions,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1Condition: A condition necessary
// for an `AccessLevel` to be granted. The Condition is an
// AND over its fields. So a Condition is true if: 1) the request IP is
// from one
// of the listed subnetworks AND 2) the originating device complies with
// the
// listed device policy AND 3) all listed access levels are granted AND
// 4) the
// request was sent at a time allowed by the DateTimeRestriction.
type GoogleIdentityAccesscontextmanagerV1Condition struct {
	// DevicePolicy: Device specific restrictions, all restrictions must
	// hold for the
	// Condition to be true. If not specified, all devices are allowed.
	DevicePolicy *GoogleIdentityAccesscontextmanagerV1DevicePolicy `json:"devicePolicy,omitempty"`

	// IpSubnetworks: CIDR block IP subnetwork specification. May be IPv4 or
	// IPv6. Note that for
	// a CIDR IP address block, the specified IP address portion must be
	// properly
	// truncated (i.e. all the host bits must be zero) or the input is
	// considered
	// malformed. For example, "192.0.2.0/24" is accepted but "192.0.2.1/24"
	// is
	// not. Similarly, for IPv6, "2001:db8::/32" is accepted
	// whereas
	// "2001:db8::1/32" is not. The originating IP of a request must be in
	// one of
	// the listed subnets in order for this Condition to be true. If empty,
	// all IP
	// addresses are allowed.
	IpSubnetworks []string `json:"ipSubnetworks,omitempty"`

	// Members: The request must be made by one of the provided user or
	// service
	// accounts. Groups are not
	// supported.
	// Syntax:
	// `user:{emailid}`
	// `serviceAccount:{emailid}`
	// If not specified, a request may come from any user.
	Members []string `json:"members,omitempty"`

	// Negate: Whether to negate the Condition. If true, the Condition
	// becomes a NAND over
	// its non-empty fields, each field must be false for the Condition
	// overall to
	// be satisfied. Defaults to false.
	Negate bool `json:"negate,omitempty"`

	// Regions: The request must originate from one of the provided
	// countries/regions.
	// Must be valid ISO 3166-1 alpha-2 codes.
	Regions []string `json:"regions,omitempty"`

	// RequiredAccessLevels: A list of other access levels defined in the
	// same `Policy`, referenced by
	// resource name. Referencing an `AccessLevel` which does not exist is
	// an
	// error. All access levels listed must be granted for the Condition
	// to be true.
	// Example:
	// "accessPolicies/MY_POLICY/accessLevels/LEVEL_NAME"
	RequiredAccessLevels []string `json:"requiredAccessLevels,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1CustomLevel: `CustomLevel` is an
// `AccessLevel` using the Cloud Common Expression Language
// to represent the necessary conditions for the level to apply to a
// request.
// See CEL spec at: https://github.com/google/cel-spec
type GoogleIdentityAccesscontextmanagerV1CustomLevel struct {
	// Expr: Required. A Cloud CEL expression evaluating to a boolean.
	Expr *Expr `json:"expr,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1DevicePolicy: `DevicePolicy`
// specifies device specific restrictions necessary to acquire a
// given access level. A `DevicePolicy` specifies requirements for
// requests from
// devices to be granted access levels, it does not do any enforcement
// on the
// device. `DevicePolicy` acts as an AND over all specified fields, and
// each
// repeated field is an OR over its elements. Any unset fields are
// ignored. For
// example, if the proto is { os_type : DESKTOP_WINDOWS, os_type
// :
// DESKTOP_LINUX, encryption_status: ENCRYPTED}, then the DevicePolicy
// will be
// true for requests originating from encrypted Linux desktops and
// encrypted
// Windows desktops.
type GoogleIdentityAccesscontextmanagerV1DevicePolicy struct {
	// AllowedDeviceManagementLevels: Allowed device management levels, an
	// empty list allows all management
	// levels.
	//
	// Possible values:
	//   "MANAGEMENT_UNSPECIFIED" - The device's management level is not
	// specified or not known.
	//   "NONE" - The device is not managed.
	//   "BASIC" - Basic management is enabled, which is generally limited
	// to monitoring and
	// wiping the corporate account.
	//   "COMPLETE" - Complete device management. This includes more
	// thorough monitoring and the
	// ability to directly manage the device (such as remote wiping). This
	// can be
	// enabled through the Android Enterprise Platform.
	AllowedDeviceManagementLevels []string `json:"allowedDeviceManagementLevels,omitempty"`

	// AllowedEncryptionStatuses: Allowed encryptions statuses, an empty
	// list allows all statuses.
	//
	// Possible values:
	//   "ENCRYPTION_UNSPECIFIED" - The encryption status of the device is
	// not specified or not known.
	//   "ENCRYPTION_UNSUPPORTED" - The device does not support encryption.
	//   "UNENCRYPTED" - The device supports encryption, but is currently
	// unencrypted.
	//   "ENCRYPTED" - The device is encrypted.
	AllowedEncryptionStatuses []string `json:"allowedEncryptionStatuses,omitempty"`

	// OsConstraints: Allowed OS versions, an empty list allows all types
	// and all versions.
	OsConstraints []*GoogleIdentityAccesscontextmanagerV1OsConstraint `json:"osConstraints,omitempty"`

	// RequireAdminApproval: Whether the device needs to be approved by the
	// customer admin.
	RequireAdminApproval bool `json:"requireAdminApproval,omitempty"`

	// RequireCorpOwned: Whether the device needs to be corp owned.
	RequireCorpOwned bool `json:"requireCorpOwned,omitempty"`

	// RequireScreenlock: Whether or not screenlock is required for the
	// DevicePolicy to be true.
	// Defaults to `false`.
	RequireScreenlock bool `json:"requireScreenlock,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1OsConstraint: A restriction on
// the OS type and version of devices making requests.
type GoogleIdentityAccesscontextmanagerV1OsConstraint struct {
	// MinimumVersion: The minimum allowed OS version. If not set, any
	// version of this OS
	// satisfies the constraint. Format: "major.minor.patch".
	// Examples: "10.5.301", "9.2.1".
	MinimumVersion string `json:"minimumVersion,omitempty"`

	// OsType: Required. The allowed OS type.
	//
	// Possible values:
	//   "OS_UNSPECIFIED" - The operating system of the device is not
	// specified or not known.
	//   "DESKTOP_MAC" - A desktop Mac operating system.
	//   "DESKTOP_WINDOWS" - A desktop Windows operating system.
	//   "DESKTOP_LINUX" - A desktop Linux operating system.
	//   "DESKTOP_CHROME_OS" - A desktop ChromeOS operating system.
	//   "ANDROID" - An Android operating system.
	//   "IOS" - An iOS operating system.
	OsType string `json:"osType,omitempty"`

	// RequireVerifiedChromeOs: Only allows requests from devices with a
	// verified Chrome OS.
	// Verifications includes requirements that the device is
	// enterprise-managed,
	// conformant to domain policies, and the caller has permission to
	// call
	// the API targeted by the request.
	RequireVerifiedChromeOs bool `json:"requireVerifiedChromeOs,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1ServicePerimeter:
// `ServicePerimeter` describes a set of Google Cloud resources which
// can freely
// import and export data amongst themselves, but not export outside of
// the
// `ServicePerimeter`. If a request with a source within this
// `ServicePerimeter`
// has a target outside of the `ServicePerimeter`, the request will be
// blocked.
// Otherwise the request is allowed. There are two types of Service
// Perimeter -
// Regular and Bridge. Regular Service Perimeters cannot overlap, a
// single
// Google Cloud project can only belong to a single regular Service
// Perimeter.
// Service Perimeter Bridges can contain only Google Cloud projects as
// members,
// a single Google Cloud project may belong to multiple Service
// Perimeter
// Bridges.
type GoogleIdentityAccesscontextmanagerV1ServicePerimeter struct {
	// CreateTime: Output only. Time the `ServicePerimeter` was created in
	// UTC.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Description of the `ServicePerimeter` and its use. Does
	// not affect
	// behavior.
	Description string `json:"description,omitempty"`

	// Name: Required. Resource name for the ServicePerimeter.  The
	// `short_name`
	// component must begin with a letter and only include alphanumeric and
	// '_'.
	// Format: `accessPolicies/{policy_id}/servicePerimeters/{short_name}`
	Name string `json:"name,omitempty"`

	// PerimeterType: Perimeter type indicator. A single project is
	// allowed to be a member of single regular perimeter, but multiple
	// service
	// perimeter bridges. A project cannot be a included in a perimeter
	// bridge
	// without being included in regular perimeter. For perimeter
	// bridges,
	// the restricted service list as well as access level lists must
	// be
	// empty.
	//
	// Possible values:
	//   "PERIMETER_TYPE_REGULAR" - Regular Perimeter.
	//   "PERIMETER_TYPE_BRIDGE" - Perimeter Bridge.
	PerimeterType string `json:"perimeterType,omitempty"`

	// Spec: Proposed (or dry run) ServicePerimeter configuration. This
	// configuration
	// allows to specify and test ServicePerimeter configuration without
	// enforcing
	// actual access restrictions. Only allowed to be set when
	// the
	// "use_explicit_dry_run_spec" flag is set.
	Spec *GoogleIdentityAccesscontextmanagerV1ServicePerimeterConfig `json:"spec,omitempty"`

	// Status: Current ServicePerimeter configuration. Specifies sets of
	// resources,
	// restricted services and access levels that determine
	// perimeter
	// content and boundaries.
	Status *GoogleIdentityAccesscontextmanagerV1ServicePerimeterConfig `json:"status,omitempty"`

	// Title: Human readable title. Must be unique within the Policy.
	Title string `json:"title,omitempty"`

	// UpdateTime: Output only. Time the `ServicePerimeter` was updated in
	// UTC.
	UpdateTime string `json:"updateTime,omitempty"`

	// UseExplicitDryRunSpec: Use explicit dry run spec flag. Ordinarily, a
	// dry-run spec implicitly
	// exists  for all Service Perimeters, and that spec is identical to
	// the
	// status for those Service Perimeters. When this flag is set, it
	// inhibits the
	// generation of the implicit spec, thereby allowing the user to
	// explicitly
	// provide a configuration ("spec") to use in a dry-run version of the
	// Service
	// Perimeter. This allows the user to test changes to the enforced
	// config
	// ("status") without actually enforcing them. This testing is done
	// through
	// analyzing the differences between currently enforced and
	// suggested
	// restrictions. use_explicit_dry_run_spec must bet set to True if any
	// of the
	// fields in the spec are set to non-default values.
	UseExplicitDryRunSpec bool `json:"useExplicitDryRunSpec,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1ServicePerimeterConfig:
// `ServicePerimeterConfig` specifies a set of Google Cloud resources
// that
// describe specific Service Perimeter configuration.
type GoogleIdentityAccesscontextmanagerV1ServicePerimeterConfig struct {
	// AccessLevels: A list of `AccessLevel` resource names that allow
	// resources within the
	// `ServicePerimeter` to be accessed from the internet. `AccessLevels`
	// listed
	// must be in the same policy as this `ServicePerimeter`. Referencing
	// a
	// nonexistent `AccessLevel` is a syntax error. If no `AccessLevel`
	// names are
	// listed, resources within the perimeter can only be accessed via
	// Google
	// Cloud calls with request origins within the perimeter.
	// Example:
	// "accessPolicies/MY_POLICY/accessLevels/MY_LEVEL".
	// For Service Perimeter Bridge, must be empty.
	AccessLevels []string `json:"accessLevels,omitempty"`

	// Resources: A list of Google Cloud resources that are inside of the
	// service perimeter.
	// Currently only projects are allowed. Format:
	// `projects/{project_number}`
	Resources []string `json:"resources,omitempty"`

	// RestrictedServices: Google Cloud services that are subject to the
	// Service Perimeter
	// restrictions. For example, if `storage.googleapis.com` is specified,
	// access
	// to the storage buckets inside the perimeter must meet the
	// perimeter's
	// access restrictions.
	RestrictedServices []string `json:"restrictedServices,omitempty"`

	// VpcAccessibleServices: Configuration for APIs allowed within
	// Perimeter.
	VpcAccessibleServices *GoogleIdentityAccesscontextmanagerV1VpcAccessibleServices `json:"vpcAccessibleServices,omitempty"`

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

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

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

// GoogleIdentityAccesscontextmanagerV1VpcAccessibleServices: Specifies
// how APIs are allowed to communicate within the Service
// Perimeter.
type GoogleIdentityAccesscontextmanagerV1VpcAccessibleServices struct {
	// AllowedServices: The list of APIs usable within the Service
	// Perimeter. Must be empty
	// unless 'enable_restriction' is True.
	AllowedServices []string `json:"allowedServices,omitempty"`

	// EnableRestriction: Whether to restrict API calls within the Service
	// Perimeter to the list of
	// APIs specified in 'allowed_services'.
	EnableRestriction bool `json:"enableRestriction,omitempty"`

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

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

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

type ListFeedsResponse struct {
	// Feeds: A list of feeds.
	Feeds []*Feed `json:"feeds,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

// OutputConfig: Output configuration for export assets destination.
type OutputConfig struct {
	// BigqueryDestination: Destination on BigQuery. The output table stores
	// the fields in asset
	// proto as columns in BigQuery. The resource/iam_policy field is
	// converted
	// to a record with each field to a column, except metadata to a single
	// JSON
	// string.
	BigqueryDestination *BigQueryDestination `json:"bigqueryDestination,omitempty"`

	// GcsDestination: Destination on Cloud Storage.
	GcsDestination *GcsDestination `json:"gcsDestination,omitempty"`

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

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

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

// Policy: An Identity and Access Management (IAM) policy, which
// specifies access
// controls for Google Cloud resources.
//
//
// A `Policy` is a collection of `bindings`. A `binding` binds one or
// more
// `members` to a single `role`. Members can be user accounts, service
// accounts,
// Google groups, and domains (such as G Suite). A `role` is a named
// list of
// permissions; each `role` can be an IAM predefined role or a
// user-created
// custom role.
//
// Optionally, a `binding` can specify a `condition`, which is a
// logical
// expression that allows access to a resource only if the expression
// evaluates
// to `true`. A condition can add constraints based on attributes of
// the
// request, the resource, or both.
//
// **JSON example:**
//
//     {
//       "bindings": [
//         {
//           "role": "roles/resourcemanager.organizationAdmin",
//           "members": [
//             "user:mike@example.com",
//             "group:admins@example.com",
//             "domain:google.com",
//
// "serviceAccount:my-project-id@appspot.gserviceaccount.com"
//           ]
//         },
//         {
//           "role": "roles/resourcemanager.organizationViewer",
//           "members": ["user:eve@example.com"],
//           "condition": {
//             "title": "expirable access",
//             "description": "Does not grant access after Sep 2020",
//             "expression": "request.time <
// timestamp('2020-10-01T00:00:00.000Z')",
//           }
//         }
//       ],
//       "etag": "BwWWja0YfJA=",
//       "version": 3
//     }
//
// **YAML example:**
//
//     bindings:
//     - members:
//       - user:mike@example.com
//       - group:admins@example.com
//       - domain:google.com
//       - serviceAccount:my-project-id@appspot.gserviceaccount.com
//       role: roles/resourcemanager.organizationAdmin
//     - members:
//       - user:eve@example.com
//       role: roles/resourcemanager.organizationViewer
//       condition:
//         title: expirable access
//         description: Does not grant access after Sep 2020
//         expression: request.time <
// timestamp('2020-10-01T00:00:00.000Z')
//     - etag: BwWWja0YfJA=
//     - version: 3
//
// For a description of IAM and its features, see the
// [IAM documentation](https://cloud.google.com/iam/docs/).
type Policy struct {
	// AuditConfigs: Specifies cloud audit logging configuration for this
	// policy.
	AuditConfigs []*AuditConfig `json:"auditConfigs,omitempty"`

	// Bindings: Associates a list of `members` to a `role`. Optionally, may
	// specify a
	// `condition` that determines how and when the `bindings` are applied.
	// Each
	// of the `bindings` must contain at least one member.
	Bindings []*Binding `json:"bindings,omitempty"`

	// Etag: `etag` is used for optimistic concurrency control as a way to
	// help
	// prevent simultaneous updates of a policy from overwriting each
	// other.
	// It is strongly suggested that systems make use of the `etag` in
	// the
	// read-modify-write cycle to perform policy updates in order to avoid
	// race
	// conditions: An `etag` is returned in the response to `getIamPolicy`,
	// and
	// systems are expected to put that etag in the request to
	// `setIamPolicy` to
	// ensure that their change will be applied to the same version of the
	// policy.
	//
	// **Important:** If you use IAM Conditions, you must include the `etag`
	// field
	// whenever you call `setIamPolicy`. If you omit this field, then IAM
	// allows
	// you to overwrite a version `3` policy with a version `1` policy, and
	// all of
	// the conditions in the version `3` policy are lost.
	Etag string `json:"etag,omitempty"`

	// Version: Specifies the format of the policy.
	//
	// Valid values are `0`, `1`, and `3`. Requests that specify an invalid
	// value
	// are rejected.
	//
	// Any operation that affects conditional role bindings must specify
	// version
	// `3`. This requirement applies to the following operations:
	//
	// * Getting a policy that includes a conditional role binding
	// * Adding a conditional role binding to a policy
	// * Changing a conditional role binding in a policy
	// * Removing any role binding, with or without a condition, from a
	// policy
	//   that includes conditions
	//
	// **Important:** If you use IAM Conditions, you must include the `etag`
	// field
	// whenever you call `setIamPolicy`. If you omit this field, then IAM
	// allows
	// you to overwrite a version `3` policy with a version `1` policy, and
	// all of
	// the conditions in the version `3` policy are lost.
	//
	// If a policy does not include any conditions, operations on that
	// policy may
	// specify any valid version or leave the field unset.
	Version int64 `json:"version,omitempty"`

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

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

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

// PubsubDestination: A Cloud Pubsub destination.
type PubsubDestination struct {
	// Topic: The name of the Cloud Pub/Sub topic to publish to.
	// For example: `projects/PROJECT_ID/topics/TOPIC_ID`.
	Topic string `json:"topic,omitempty"`

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

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

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

// Resource: A representation of a Google Cloud resource.
type Resource struct {
	// Data: The content of the resource, in which some sensitive fields are
	// removed
	// and may not be present.
	Data googleapi.RawMessage `json:"data,omitempty"`

	// DiscoveryDocumentUri: The URL of the discovery document containing
	// the resource's JSON schema.
	// For
	// example:
	// "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest
	// "
	//
	// This value is unspecified for resources that do not have an API based
	// on a
	// discovery document, such as Cloud Bigtable.
	DiscoveryDocumentUri string `json:"discoveryDocumentUri,omitempty"`

	// DiscoveryName: The JSON schema name listed in the discovery document.
	// For example:
	// "Project"
	//
	// This value is unspecified for resources that do not have an API based
	// on a
	// discovery document, such as Cloud Bigtable.
	DiscoveryName string `json:"discoveryName,omitempty"`

	// Parent: The full name of the immediate parent of this resource.
	// See
	// [Resource
	// Names](https://cloud.google.com/apis/design/resource_nam
	// es#full_resource_name)
	// for more information.
	//
	// For Google Cloud assets, this value is the parent resource defined in
	// the
	// [Cloud IAM
	// policy
	// hierarchy](https://cloud.google.com/iam/docs/overview#policy_hi
	// erarchy).
	// For
	// example:
	// "//cloudresourcemanager.googleapis.com/projects/my_project_12
	// 3"
	//
	// For third-party assets, this field may be set differently.
	Parent string `json:"parent,omitempty"`

	// ResourceUrl: The REST URL for accessing the resource. An HTTP `GET`
	// request using this
	// URL returns the resource itself. For
	// example:
	// "https://cloudresourcemanager.googleapis.com/v1/projects/my-p
	// roject-123"
	//
	// This value is unspecified for resources without a REST API.
	ResourceUrl string `json:"resourceUrl,omitempty"`

	// Version: The API version. For example: "v1"
	Version string `json:"version,omitempty"`

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

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

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

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

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

	// Message: A developer-facing error message, which should be in
	// English. Any
	// user-facing error message should be localized and sent in
	// the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

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

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

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

// TemporalAsset: An asset in Google Cloud and its temporal metadata,
// including the time window
// when it was observed and its status during that window.
type TemporalAsset struct {
	// Asset: An asset in Google Cloud.
	Asset *Asset `json:"asset,omitempty"`

	// Deleted: Whether the asset has been deleted or not.
	Deleted bool `json:"deleted,omitempty"`

	// Window: The time window when the asset data and state was observed.
	Window *TimeWindow `json:"window,omitempty"`

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

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

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

// TimeWindow: A time window specified by its "start_time" and
// "end_time".
type TimeWindow struct {
	// EndTime: End time of the time window (inclusive). If not specified,
	// the current
	// timestamp is used instead.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Start time of the time window (exclusive).
	StartTime string `json:"startTime,omitempty"`

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

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

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

// UpdateFeedRequest: Update asset feed request.
type UpdateFeedRequest struct {
	// Feed: Required. The new values of feed details. It must match an
	// existing feed and the
	// field `name` must be in the format
	// of:
	// projects/project_number/feeds/feed_id
	// or
	// folders/folder_number/feeds/feed_id
	// or
	// organizations/organization_number/feeds/feed_id.
	Feed *Feed `json:"feed,omitempty"`

	// UpdateMask: Required. Only updates the `feed` fields indicated by
	// this mask.
	// The field mask must not be empty, and it must not contain fields
	// that
	// are immutable or only set by the server.
	UpdateMask string `json:"updateMask,omitempty"`

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

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

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

// method id "cloudasset.feeds.create":

type FeedsCreateCall struct {
	s                 *Service
	parent            string
	createfeedrequest *CreateFeedRequest
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates a feed in a parent project/folder/organization to
// listen to its
// asset updates.
func (r *FeedsService) Create(parent string, createfeedrequest *CreateFeedRequest) *FeedsCreateCall {
	c := &FeedsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.createfeedrequest = createfeedrequest
	return c
}

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

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

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

func (c *FeedsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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.createfeedrequest)
	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}/feeds")
	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 "cloudasset.feeds.create" call.
// Exactly one of *Feed or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Feed.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FeedsCreateCall) Do(opts ...googleapi.CallOption) (*Feed, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Feed{
		ServerResponse: googleapi.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 feed in a parent project/folder/organization to listen to its\nasset updates.",
	//   "flatPath": "v1/{v1Id}/{v1Id1}/feeds",
	//   "httpMethod": "POST",
	//   "id": "cloudasset.feeds.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the project/folder/organization where this feed\nshould be created in. It can only be an organization number (such as\n\"organizations/123\"), a folder number (such as \"folders/123\"), a project ID\n(such as \"projects/my-project-id\")\", or a project number (such as\n\"projects/12345\").",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/feeds",
	//   "request": {
	//     "$ref": "CreateFeedRequest"
	//   },
	//   "response": {
	//     "$ref": "Feed"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudasset.feeds.delete":

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

// Delete: Deletes an asset feed.
func (r *FeedsService) Delete(name string) *FeedsDeleteCall {
	c := &FeedsDeleteCall{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 *FeedsDeleteCall) Fields(s ...googleapi.Field) *FeedsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

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

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

func (c *FeedsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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 "cloudasset.feeds.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 *FeedsDeleteCall) 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 an asset feed.",
	//   "flatPath": "v1/{v1Id}/{v1Id1}/feeds/{feedsId}",
	//   "httpMethod": "DELETE",
	//   "id": "cloudasset.feeds.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the feed and it must be in the format of:\nprojects/project_number/feeds/feed_id\nfolders/folder_number/feeds/feed_id\norganizations/organization_number/feeds/feed_id",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/feeds/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudasset.feeds.get":

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

// Get: Gets details about an asset feed.
func (r *FeedsService) Get(name string) *FeedsGetCall {
	c := &FeedsGetCall{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 *FeedsGetCall) Fields(s ...googleapi.Field) *FeedsGetCall {
	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 *FeedsGetCall) IfNoneMatch(entityTag string) *FeedsGetCall {
	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 *FeedsGetCall) Context(ctx context.Context) *FeedsGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *FeedsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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 "cloudasset.feeds.get" call.
// Exactly one of *Feed or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Feed.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FeedsGetCall) Do(opts ...googleapi.CallOption) (*Feed, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Feed{
		ServerResponse: googleapi.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 details about an asset feed.",
	//   "flatPath": "v1/{v1Id}/{v1Id1}/feeds/{feedsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudasset.feeds.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the Feed and it must be in the format of:\nprojects/project_number/feeds/feed_id\nfolders/folder_number/feeds/feed_id\norganizations/organization_number/feeds/feed_id",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/feeds/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Feed"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudasset.feeds.list":

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

// List: Lists all asset feeds in a parent project/folder/organization.
func (r *FeedsService) List(parent string) *FeedsListCall {
	c := &FeedsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

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

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

func (c *FeedsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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}/feeds")
	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 "cloudasset.feeds.list" call.
// Exactly one of *ListFeedsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListFeedsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FeedsListCall) Do(opts ...googleapi.CallOption) (*ListFeedsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListFeedsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists all asset feeds in a parent project/folder/organization.",
	//   "flatPath": "v1/{v1Id}/{v1Id1}/feeds",
	//   "httpMethod": "GET",
	//   "id": "cloudasset.feeds.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent project/folder/organization whose feeds are to be\nlisted. It can only be using project/folder/organization number (such as\n\"folders/12345\")\", or a project ID (such as \"projects/my-project-id\").",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/feeds",
	//   "response": {
	//     "$ref": "ListFeedsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudasset.feeds.patch":

type FeedsPatchCall struct {
	s                 *Service
	nameid            string
	updatefeedrequest *UpdateFeedRequest
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Patch: Updates an asset feed configuration.
func (r *FeedsService) Patch(nameid string, updatefeedrequest *UpdateFeedRequest) *FeedsPatchCall {
	c := &FeedsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.updatefeedrequest = updatefeedrequest
	return c
}

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

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

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

func (c *FeedsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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.updatefeedrequest)
	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}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudasset.feeds.patch" call.
// Exactly one of *Feed or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Feed.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FeedsPatchCall) Do(opts ...googleapi.CallOption) (*Feed, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Feed{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an asset feed configuration.",
	//   "flatPath": "v1/{v1Id}/{v1Id1}/feeds/{feedsId}",
	//   "httpMethod": "PATCH",
	//   "id": "cloudasset.feeds.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The format will be\nprojects/{project_number}/feeds/{client-assigned_feed_identifier} or\nfolders/{folder_number}/feeds/{client-assigned_feed_identifier} or\norganizations/{organization_number}/feeds/{client-assigned_feed_identifier}\n\nThe client-assigned feed identifier must be unique within the parent\nproject/folder/organization.",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+/feeds/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "UpdateFeedRequest"
	//   },
	//   "response": {
	//     "$ref": "Feed"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

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

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

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

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

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

func (c *OperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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 "cloudasset.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/{v1Id}/{v1Id1}/operations/{operationsId}/{operationsId1}",
	//   "httpMethod": "GET",
	//   "id": "cloudasset.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 "cloudasset.batchGetAssetsHistory":

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

// BatchGetAssetsHistory: Batch gets the update history of assets that
// overlap a time window.
// For RESOURCE content, this API outputs history with asset in
// both
// non-delete or deleted status.
// For IAM_POLICY content, this API outputs history when the asset and
// its
// attached IAM POLICY both exist. This can create gaps in the output
// history.
// If a specified asset does not exist, this API returns an
// INVALID_ARGUMENT
// error.
func (r *V1Service) BatchGetAssetsHistory(parent string) *V1BatchGetAssetsHistoryCall {
	c := &V1BatchGetAssetsHistoryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// AssetNames sets the optional parameter "assetNames": A list of the
// full names of the assets. For
// example:
// `//compute.googleapis.com/projects/my_project_123/zones/zone1
// /instances/instance1`.
// See
// [Resource
// Names](https://cloud.google.com/apis/design/resource_names#f
// ull_resource_name)
// and [Resource
// Name
// Format](https://cloud.google.com/asset-inventory/docs/resource-na
// me-format)
// for more info.
//
// The request becomes a no-op if the asset name list is empty, and the
// max
// size of the asset name list is 100 in one request.
func (c *V1BatchGetAssetsHistoryCall) AssetNames(assetNames ...string) *V1BatchGetAssetsHistoryCall {
	c.urlParams_.SetMulti("assetNames", append([]string{}, assetNames...))
	return c
}

// ContentType sets the optional parameter "contentType": The content
// type.
//
// Possible values:
//   "CONTENT_TYPE_UNSPECIFIED"
//   "RESOURCE"
//   "IAM_POLICY"
//   "ORG_POLICY"
//   "ACCESS_POLICY"
func (c *V1BatchGetAssetsHistoryCall) ContentType(contentType string) *V1BatchGetAssetsHistoryCall {
	c.urlParams_.Set("contentType", contentType)
	return c
}

// ReadTimeWindowEndTime sets the optional parameter
// "readTimeWindow.endTime": End time of the time window (inclusive). If
// not specified, the current
// timestamp is used instead.
func (c *V1BatchGetAssetsHistoryCall) ReadTimeWindowEndTime(readTimeWindowEndTime string) *V1BatchGetAssetsHistoryCall {
	c.urlParams_.Set("readTimeWindow.endTime", readTimeWindowEndTime)
	return c
}

// ReadTimeWindowStartTime sets the optional parameter
// "readTimeWindow.startTime": Start time of the time window
// (exclusive).
func (c *V1BatchGetAssetsHistoryCall) ReadTimeWindowStartTime(readTimeWindowStartTime string) *V1BatchGetAssetsHistoryCall {
	c.urlParams_.Set("readTimeWindow.startTime", readTimeWindowStartTime)
	return c
}

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

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

func (c *V1BatchGetAssetsHistoryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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}:batchGetAssetsHistory")
	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 "cloudasset.batchGetAssetsHistory" call.
// Exactly one of *BatchGetAssetsHistoryResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchGetAssetsHistoryResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *V1BatchGetAssetsHistoryCall) Do(opts ...googleapi.CallOption) (*BatchGetAssetsHistoryResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchGetAssetsHistoryResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Batch gets the update history of assets that overlap a time window.\nFor RESOURCE content, this API outputs history with asset in both\nnon-delete or deleted status.\nFor IAM_POLICY content, this API outputs history when the asset and its\nattached IAM POLICY both exist. This can create gaps in the output history.\nIf a specified asset does not exist, this API returns an INVALID_ARGUMENT\nerror.",
	//   "flatPath": "v1/{v1Id}/{v1Id1}:batchGetAssetsHistory",
	//   "httpMethod": "GET",
	//   "id": "cloudasset.batchGetAssetsHistory",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "assetNames": {
	//       "description": "A list of the full names of the assets. For example:\n`//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`.\nSee [Resource\nNames](https://cloud.google.com/apis/design/resource_names#full_resource_name)\nand [Resource Name\nFormat](https://cloud.google.com/asset-inventory/docs/resource-name-format)\nfor more info.\n\nThe request becomes a no-op if the asset name list is empty, and the max\nsize of the asset name list is 100 in one request.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "contentType": {
	//       "description": "Optional. The content type.",
	//       "enum": [
	//         "CONTENT_TYPE_UNSPECIFIED",
	//         "RESOURCE",
	//         "IAM_POLICY",
	//         "ORG_POLICY",
	//         "ACCESS_POLICY"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The relative name of the root asset. It can only be an\norganization number (such as \"organizations/123\"), a project ID (such as\n\"projects/my-project-id\")\", or a project number (such as \"projects/12345\").",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readTimeWindow.endTime": {
	//       "description": "End time of the time window (inclusive). If not specified, the current\ntimestamp is used instead.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "readTimeWindow.startTime": {
	//       "description": "Start time of the time window (exclusive).",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}:batchGetAssetsHistory",
	//   "response": {
	//     "$ref": "BatchGetAssetsHistoryResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudasset.exportAssets":

type V1ExportAssetsCall struct {
	s                   *Service
	parent              string
	exportassetsrequest *ExportAssetsRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// ExportAssets: Exports assets with time and resource types to a given
// Cloud Storage
// location. The output format is newline-delimited JSON.
// This API implements the google.longrunning.Operation API allowing
// you
// to keep track of the export.
func (r *V1Service) ExportAssets(parent string, exportassetsrequest *ExportAssetsRequest) *V1ExportAssetsCall {
	c := &V1ExportAssetsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.exportassetsrequest = exportassetsrequest
	return c
}

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

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

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

func (c *V1ExportAssetsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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.exportassetsrequest)
	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}:exportAssets")
	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 "cloudasset.exportAssets" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *V1ExportAssetsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Exports assets with time and resource types to a given Cloud Storage\nlocation. The output format is newline-delimited JSON.\nThis API implements the google.longrunning.Operation API allowing you\nto keep track of the export.",
	//   "flatPath": "v1/{v1Id}/{v1Id1}:exportAssets",
	//   "httpMethod": "POST",
	//   "id": "cloudasset.exportAssets",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The relative name of the root asset. This can only be an\norganization number (such as \"organizations/123\"), a project ID (such as\n\"projects/my-project-id\"), or a project number (such as \"projects/12345\"),\nor a folder number (such as \"folders/123\").",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}:exportAssets",
	//   "request": {
	//     "$ref": "ExportAssetsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
