// 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/v1p5beta1"
//   ...
//   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/v1p5beta1"

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:v1p5beta1"
const apiName = "cloudasset"
const apiVersion = "v1p5beta1"
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.Assets = NewAssetsService(s)
	return s, nil
}

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

	Assets *AssetsService
}

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

func NewAssetsService(s *Service) *AssetsService {
	rs := &AssetsService{s: s}
	return rs
}

type AssetsService 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/docs/cloud-platfo
// rm-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-asset-t
// ypes) for more information.
type Asset struct {
	// AccessLevel: Please also refer to the [access level user
	// guide](https://cloud.google.com/access-context-manager/docs/overview#a
	// ccess-levels).
	AccessLevel *GoogleIdentityAccesscontextmanagerV1AccessLevel `json:"accessLevel,omitempty"`

	// AccessPolicy: Please also refer to the [access policy user
	// guide](https://cloud.google.com/access-context-manager/docs/overview#a
	// ccess-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/cloud-platfo
	// rm-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-asset-t
	// ypes) 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/instance
	// s/instance1` See [Resource
	// names](https://cloud.google.com/apis/design/resource_names#full_resour
	// ce_name) for more information.
	Name string `json:"name,omitempty"`

	// OrgPolicy: A representation of an [organization
	// policy](https://cloud.google.com/resource-manager/docs/organization-po
	// licy/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/overview).
	ServicePerimeter *GoogleIdentityAccesscontextmanagerV1ServicePerimeter `json:"servicePerimeter,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

// 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/resource-p
	// olicies).
	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)
}

// 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)
}

// 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/", e.g.
// "projects/tokyo-rain-123" - "folders/", e.g. "folders/1234" -
// "organizations/", 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-con
	// straints) 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. You can
	// specify a list of individual services, as well as include the
	// 'RESTRICTED-SERVICES' value, which automatically includes all of the
	// services protected by the perimeter.
	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)
}

// ListAssetsResponse: ListAssets response.
type ListAssetsResponse struct {
	// Assets: Assets.
	Assets []*Asset `json:"assets,omitempty"`

	// NextPageToken: Token to retrieve the next page of results. Set to
	// empty if there are no remaining results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ReadTime: Time the snapshot was taken.
	ReadTime string `json:"readTime,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 *ListAssetsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAssetsResponse
	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)
}

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

	// Parent: The full name of the immediate parent of this resource. See
	// [Resource
	// Names](https://cloud.google.com/apis/design/resource_names#full_resour
	// ce_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_hierarchy
	// ). 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-project-12
	// 3` 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)
}

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

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

// List: Lists assets with time and resource types and returns paged
// results in response.
func (r *AssetsService) List(parent string) *AssetsListCall {
	c := &AssetsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// AssetTypes sets the optional parameter "assetTypes": A list of asset
// types to take a snapshot for. For example:
// "compute.googleapis.com/Disk". Regular expression is also supported.
// For example: * "compute.googleapis.com.*" snapshots resources whose
// asset type starts with "compute.googleapis.com". * ".*Instance"
// snapshots resources whose asset type ends with "Instance". *
// ".*Instance.*" snapshots resources whose asset type contains
// "Instance". See [RE2](https://github.com/google/re2/wiki/Syntax) for
// all supported regular expression syntax. If the regular expression
// does not match any supported asset type, an INVALID_ARGUMENT error
// will be returned. If specified, only matching assets will be
// returned, otherwise, it will snapshot all asset types. See
// [Introduction to Cloud Asset
// Inventory](https://cloud.google.com/asset-inventory/docs/overview)
// for all supported asset types.
func (c *AssetsListCall) AssetTypes(assetTypes ...string) *AssetsListCall {
	c.urlParams_.SetMulti("assetTypes", append([]string{}, assetTypes...))
	return c
}

// ContentType sets the optional parameter "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.
func (c *AssetsListCall) ContentType(contentType string) *AssetsListCall {
	c.urlParams_.Set("contentType", contentType)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of assets to be returned in a single response. Default is 100,
// minimum is 1, and maximum is 1000.
func (c *AssetsListCall) PageSize(pageSize int64) *AssetsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// `next_page_token` returned from the previous `ListAssetsResponse`, or
// unspecified for the first `ListAssetsRequest`. It is a continuation
// of a prior `ListAssets` call, and the API should return the next page
// of assets.
func (c *AssetsListCall) PageToken(pageToken string) *AssetsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadTime sets the optional parameter "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.
func (c *AssetsListCall) ReadTime(readTime string) *AssetsListCall {
	c.urlParams_.Set("readTime", readTime)
	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 *AssetsListCall) Fields(s ...googleapi.Field) *AssetsListCall {
	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 *AssetsListCall) IfNoneMatch(entityTag string) *AssetsListCall {
	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 *AssetsListCall) Context(ctx context.Context) *AssetsListCall {
	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 *AssetsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AssetsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200827")
	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, "v1p5beta1/{+parent}/assets")
	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.assets.list" call.
// Exactly one of *ListAssetsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListAssetsResponse.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 *AssetsListCall) Do(opts ...googleapi.CallOption) (*ListAssetsResponse, 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 := &ListAssetsResponse{
		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 assets with time and resource types and returns paged results in response.",
	//   "flatPath": "v1p5beta1/{v1p5beta1Id}/{v1p5beta1Id1}/assets",
	//   "httpMethod": "GET",
	//   "id": "cloudasset.assets.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "assetTypes": {
	//       "description": "A list of asset types to take a snapshot for. For example: \"compute.googleapis.com/Disk\". Regular expression is also supported. For example: * \"compute.googleapis.com.*\" snapshots resources whose asset type starts with \"compute.googleapis.com\". * \".*Instance\" snapshots resources whose asset type ends with \"Instance\". * \".*Instance.*\" snapshots resources whose asset type contains \"Instance\". See [RE2](https://github.com/google/re2/wiki/Syntax) for all supported regular expression syntax. If the regular expression does not match any supported asset type, an INVALID_ARGUMENT error will be returned. If specified, only matching assets will be returned, otherwise, it will snapshot all asset types. See [Introduction to Cloud Asset Inventory](https://cloud.google.com/asset-inventory/docs/overview) for all supported asset types.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "contentType": {
	//       "description": "Asset content type. If not specified, no content but the asset name will be returned.",
	//       "enum": [
	//         "CONTENT_TYPE_UNSPECIFIED",
	//         "RESOURCE",
	//         "IAM_POLICY",
	//         "ORG_POLICY",
	//         "ACCESS_POLICY"
	//       ],
	//       "enumDescriptions": [
	//         "Unspecified content type.",
	//         "Resource metadata.",
	//         "The actual IAM policy set on a resource.",
	//         "The Cloud Organization Policy set on an asset.",
	//         "The Cloud Access context mananger Policy set on an asset."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of assets to be returned in a single response. Default is 100, minimum is 1, and maximum is 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The `next_page_token` returned from the previous `ListAssetsResponse`, or unspecified for the first `ListAssetsRequest`. It is a continuation of a prior `ListAssets` call, and the API should return the next page of assets.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization or project the assets belong to. Format: \"organizations/[organization-number]\" (such as \"organizations/123\"), \"projects/[project-number]\" (such as \"projects/my-project-id\"), or \"projects/[project-id]\" (such as \"projects/12345\").",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readTime": {
	//       "description": "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.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p5beta1/{+parent}/assets",
	//   "response": {
	//     "$ref": "ListAssetsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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