// 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/"
const mtlsBasePath = "https://cloudasset.mtls.googleapis.com/"

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

// 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))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new 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 policy (e.g. Cloud IAM
// policy).
// See [Supported
// asset
// types](https://cloud.google.com/asset-inventory/docs/supported-a
// sset-types)
// for more information.
type Asset struct {
	// AccessLevel: Please also refer to the [access level
	// user
	// guide](https://cloud.google.com/access-context-manager/docs/overv
	// iew#access-levels).
	AccessLevel *GoogleIdentityAccesscontextmanagerV1AccessLevel `json:"accessLevel,omitempty"`

	// AccessPolicy: Please also refer to the [access policy
	// user
	// guide](https://cloud.google.com/access-context-manager/docs/overv
	// iew#access-policies).
	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.
	//
	// Example: `["projects/123456789", "folders/5432",
	// "organizations/1234"]`
	Ancestors []string `json:"ancestors,omitempty"`

	// AssetType: The type of the asset. 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.
	// 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: Please also refer to the [service perimeter
	// user
	// guide](https://cloud.google.com/vpc-service-controls/docs/overvie
	// w).
	ServicePerimeter *GoogleIdentityAccesscontextmanagerV1ServicePerimeter `json:"servicePerimeter,omitempty"`

	// UpdateTime: The last update timestamp of an asset. update_time is
	// updated when
	// create/update/delete operation is performed.
	UpdateTime string `json:"updateTime,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 for exporting assets to.
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 INVALID_ARGUMENT 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 `FALSE` or unset and the destination table already exists, the
	// export
	// call returns an INVALID_ARGUMEMT 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.
	//
	// If the condition evaluates to `true`, then this binding applies to
	// the
	// current request.
	//
	// If the condition evaluates to `false`, then this binding does not
	// apply to
	// the current request. However, a different role binding might grant
	// the same
	// role to one or more of the members in this binding.
	//
	// To learn which resources support conditions in their IAM policies,
	// see
	// the
	// [IAM
	// documentation](https://cloud.google.com/iam/help/conditions/r
	// esource-policies).
	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.
	// 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.
	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:
// 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 or asset_types are exported to the
	// feed.
	// 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 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 or asset_types are exported to the
	// feed.
	// 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 Pub/Sub.
	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. 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.
	// 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.
	// 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 supersedes 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`.
	//
	// A [list of
	// available
	// constraints](/resource-manager/docs/organization-policy/org-
	// policy-constraints)
	// is available.
	//
	// 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"`

	// 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"`

	// 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 {
	// 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"`

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

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

func (s *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 {
	// 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"`

	// 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. "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 *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.
	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.
//
// For some types of Google Cloud resources, a `binding` can also
// 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. To learn
// which
// resources support conditions in their IAM policies, see the
// [IAM
// documentation](https://cloud.google.com/iam/help/conditions/resource-p
// olicies).
//
// **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.
	//
	// To learn which resources support conditions in their IAM policies,
	// see the
	// [IAM
	// documentation](https://cloud.google.com/iam/help/conditions/resource-p
	// olicies).
	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 Pub/Sub destination.
type PubsubDestination struct {
	// Topic: The name of the Pub/Sub topic to publish to.
	// 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.
	// 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.
	// 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"`

	// Location: The location of the resource in Google Cloud, such as its
	// zone and region.
	// For more information, see https://cloud.google.com/about/locations/.
	Location string `json:"location,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).
	// Example:
	// `//cloudresourcemanager.googleapis.com/projects/my_
	// project_123`
	//
	// 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.
	// 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. 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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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 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.
// Otherwise, this API outputs history with asset in both non-delete
// or
// deleted status.
// 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.
// See:
// https://cloud.google.com/asset-inventory/docs/resource-name-format
// Exa
// mple:
//
// `//compute.googleapis.com/projects/my_project_123/zones/zone1/i
// nstances/instance1`.
//
// 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/20200625")
	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 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.\nOtherwise, this API outputs history with asset in both non-delete or\ndeleted status.\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.\nSee: https://cloud.google.com/asset-inventory/docs/resource-name-format\nExample:\n\n`//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`.\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/BigQuery table. For Cloud Storage location destinations,
// the
// output format is newline-delimited JSON. Each line represents
// a
// google.cloud.asset.v1.Asset in the JSON format; for BigQuery
// table
// destinations, the output table stores the fields in asset proto as
// columns.
// This API implements the google.longrunning.Operation API
// , which allows you to keep track of the export. We recommend
// intervals of
// at least 2 seconds with exponential retry to poll the export
// operation
// result. For regular-size resource parent, the export operation
// usually
// finishes within 5 minutes.
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/20200625")
	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/BigQuery table. For Cloud Storage location destinations, the\noutput format is newline-delimited JSON. Each line represents a\ngoogle.cloud.asset.v1.Asset in the JSON format; for BigQuery table\ndestinations, the output table stores the fields in asset proto as columns.\nThis API implements the google.longrunning.Operation API\n, which allows you to keep track of the export. We recommend intervals of\nat least 2 seconds with exponential retry to poll the export operation\nresult. For regular-size resource parent, the export operation usually\nfinishes within 5 minutes.",
	//   "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"
	//   ]
	// }

}
