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

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:v1p4beta1"
const apiName = "cloudasset"
const apiVersion = "v1p4beta1"
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.V1p4beta1 = NewV1p4beta1Service(s)
	return s, nil
}

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

	V1p4beta1 *V1p4beta1Service
}

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

func NewV1p4beta1Service(s *Service) *V1p4beta1Service {
	rs := &V1p4beta1Service{s: s}
	return rs
}

type V1p4beta1Service struct {
	s *Service
}

// AccessSelector: Specifies roles and/or permissions to analyze, to
// determine both the
// identities possessing them and the resources they control. If
// multiple
// values are specified, results will include identities and
// resources
// matching any of them.
type AccessSelector struct {
	// Permissions: Optional. The permissions to appear in result.
	Permissions []string `json:"permissions,omitempty"`

	// Roles: Optional. The roles to appear in result.
	Roles []string `json:"roles,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Permissions") 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. "Permissions") 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 *AccessSelector) MarshalJSON() ([]byte, error) {
	type NoMethod AccessSelector
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AnalyzeIamPolicyResponse: A response message for
// AssetService.AnalyzeIamPolicy.
type AnalyzeIamPolicyResponse struct {
	// FullyExplored: Represents whether all entries in the main_analysis
	// and
	// service_account_impersonation_analysis have been fully explored
	// to
	// answer the query in the request.
	FullyExplored bool `json:"fullyExplored,omitempty"`

	// MainAnalysis: The main analysis that matches the original request.
	MainAnalysis *IamPolicyAnalysis `json:"mainAnalysis,omitempty"`

	// NonCriticalErrors: A list of non-critical errors happened during the
	// request handling to
	// explain why `fully_explored` is false, or empty if no error happened.
	NonCriticalErrors []*GoogleCloudAssetV1p4beta1AnalysisState `json:"nonCriticalErrors,omitempty"`

	// ServiceAccountImpersonationAnalysis: The service account
	// impersonation analysis
	// if
	// AnalyzeIamPolicyRequest.analyze_service_account_impersonation
	// is
	// enabled.
	ServiceAccountImpersonationAnalysis []*IamPolicyAnalysis `json:"serviceAccountImpersonationAnalysis,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "FullyExplored") 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. "FullyExplored") 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 *AnalyzeIamPolicyResponse) MarshalJSON() ([]byte, error) {
	type NoMethod AnalyzeIamPolicyResponse
	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)
}

// ExportIamPolicyAnalysisRequest: A request message for
// AssetService.ExportIamPolicyAnalysis.
type ExportIamPolicyAnalysisRequest struct {
	// AnalysisQuery: Required. The request query.
	AnalysisQuery *IamPolicyAnalysisQuery `json:"analysisQuery,omitempty"`

	// Options: Optional. The request options.
	Options *Options `json:"options,omitempty"`

	// OutputConfig: Required. Output configuration indicating where the
	// results will be output to.
	OutputConfig *IamPolicyAnalysisOutputConfig `json:"outputConfig,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalysisQuery") 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. "AnalysisQuery") 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 *ExportIamPolicyAnalysisRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ExportIamPolicyAnalysisRequest
	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)
}

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

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

// GoogleCloudAssetV1p4beta1Access: An IAM role or permission under
// analysis.
type GoogleCloudAssetV1p4beta1Access struct {
	// AnalysisState: The analysis state of this access.
	AnalysisState *GoogleCloudAssetV1p4beta1AnalysisState `json:"analysisState,omitempty"`

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

	// Role: The role.
	Role string `json:"role,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalysisState") 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. "AnalysisState") 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 *GoogleCloudAssetV1p4beta1Access) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAssetV1p4beta1Access
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudAssetV1p4beta1AccessControlList: An access control list,
// derived from the above IAM policy binding, which
// contains a set of resources and accesses. May include one
// item from each set to compose an access control entry.
//
// NOTICE that there could be multiple access control lists for one IAM
// policy
// binding. The access control lists are created based on resource and
// access
// combinations.
//
// For example, assume we have the following cases in one IAM policy
// binding:
// - Permission P1 and P2 apply to resource R1 and R2;
// - Permission P3 applies to resource R2 and R3;
//
// This will result in the following access control lists:
// - AccessControlList 1: [R1, R2], [P1, P2]
// - AccessControlList 2: [R2, R3], [P3]
type GoogleCloudAssetV1p4beta1AccessControlList struct {
	// Accesses: The accesses that match one of the following conditions:
	// - The access_selector, if it is specified in request;
	// - Otherwise, access specifiers reachable from the policy binding's
	// role.
	Accesses []*GoogleCloudAssetV1p4beta1Access `json:"accesses,omitempty"`

	// ResourceEdges: Resource edges of the graph starting from the policy
	// attached
	// resource to any descendant resources. The Edge.source_node
	// contains
	// the full resource name of a parent resource and
	// Edge.target_node
	// contains the full resource name of a child resource. This field
	// is
	// present only if the output_resource_edges option is enabled in
	// request.
	ResourceEdges []*GoogleCloudAssetV1p4beta1Edge `json:"resourceEdges,omitempty"`

	// Resources: The resources that match one of the following
	// conditions:
	// - The resource_selector, if it is specified in request;
	// - Otherwise, resources reachable from the policy attached resource.
	Resources []*GoogleCloudAssetV1p4beta1Resource `json:"resources,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Accesses") 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. "Accesses") 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 *GoogleCloudAssetV1p4beta1AccessControlList) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAssetV1p4beta1AccessControlList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudAssetV1p4beta1AnalysisState: Represents the detailed state
// of an entity under analysis, such as a
// resource, an identity or an access.
type GoogleCloudAssetV1p4beta1AnalysisState struct {
	// Cause: The human-readable description of the cause of failure.
	Cause string `json:"cause,omitempty"`

	// Code: The Google standard error code that best describes the
	// state.
	// For example:
	// - OK means the analysis on this entity has been successfully
	// finished;
	// - PERMISSION_DENIED means an access denied error is encountered;
	// - DEADLINE_EXCEEDED means the analysis on this entity hasn't been
	// started
	// in time;
	//
	// Possible values:
	//   "OK" - Not an error; returned on success
	//
	// HTTP Mapping: 200 OK
	//   "CANCELLED" - The operation was cancelled, typically by the
	// caller.
	//
	// HTTP Mapping: 499 Client Closed Request
	//   "UNKNOWN" - Unknown error.  For example, this error may be returned
	// when
	// a `Status` value received from another address space belongs to
	// an error space that is not known in this address space.  Also
	// errors raised by APIs that do not return enough error information
	// may be converted to this error.
	//
	// HTTP Mapping: 500 Internal Server Error
	//   "INVALID_ARGUMENT" - The client specified an invalid argument.
	// Note that this differs
	// from `FAILED_PRECONDITION`.  `INVALID_ARGUMENT` indicates
	// arguments
	// that are problematic regardless of the state of the system
	// (e.g., a malformed file name).
	//
	// HTTP Mapping: 400 Bad Request
	//   "DEADLINE_EXCEEDED" - The deadline expired before the operation
	// could complete. For operations
	// that change the state of the system, this error may be returned
	// even if the operation has completed successfully.  For example,
	// a
	// successful response from a server could have been delayed long
	// enough for the deadline to expire.
	//
	// HTTP Mapping: 504 Gateway Timeout
	//   "NOT_FOUND" - Some requested entity (e.g., file or directory) was
	// not found.
	//
	// Note to server developers: if a request is denied for an entire
	// class
	// of users, such as gradual feature rollout or undocumented
	// whitelist,
	// `NOT_FOUND` may be used. If a request is denied for some users
	// within
	// a class of users, such as user-based access control,
	// `PERMISSION_DENIED`
	// must be used.
	//
	// HTTP Mapping: 404 Not Found
	//   "ALREADY_EXISTS" - The entity that a client attempted to create
	// (e.g., file or directory)
	// already exists.
	//
	// HTTP Mapping: 409 Conflict
	//   "PERMISSION_DENIED" - The caller does not have permission to
	// execute the specified
	// operation. `PERMISSION_DENIED` must not be used for rejections
	// caused by exhausting some resource (use `RESOURCE_EXHAUSTED`
	// instead for those errors). `PERMISSION_DENIED` must not be
	// used if the caller can not be identified (use
	// `UNAUTHENTICATED`
	// instead for those errors). This error code does not imply the
	// request is valid or the requested entity exists or satisfies
	// other pre-conditions.
	//
	// HTTP Mapping: 403 Forbidden
	//   "UNAUTHENTICATED" - The request does not have valid authentication
	// credentials for the
	// operation.
	//
	// HTTP Mapping: 401 Unauthorized
	//   "RESOURCE_EXHAUSTED" - Some resource has been exhausted, perhaps a
	// per-user quota, or
	// perhaps the entire file system is out of space.
	//
	// HTTP Mapping: 429 Too Many Requests
	//   "FAILED_PRECONDITION" - The operation was rejected because the
	// system is not in a state
	// required for the operation's execution.  For example, the
	// directory
	// to be deleted is non-empty, an rmdir operation is applied to
	// a non-directory, etc.
	//
	// Service implementors can use the following guidelines to
	// decide
	// between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`:
	//  (a) Use `UNAVAILABLE` if the client can retry just the failing
	// call.
	//  (b) Use `ABORTED` if the client should retry at a higher level
	//      (e.g., when a client-specified test-and-set fails, indicating
	// the
	//      client should restart a read-modify-write sequence).
	//  (c) Use `FAILED_PRECONDITION` if the client should not retry until
	//      the system state has been explicitly fixed.  E.g., if an
	// "rmdir"
	//      fails because the directory is non-empty, `FAILED_PRECONDITION`
	//      should be returned since the client should not retry unless
	//      the files are deleted from the directory.
	//
	// HTTP Mapping: 400 Bad Request
	//   "ABORTED" - The operation was aborted, typically due to a
	// concurrency issue such as
	// a sequencer check failure or transaction abort.
	//
	// See the guidelines above for deciding between
	// `FAILED_PRECONDITION`,
	// `ABORTED`, and `UNAVAILABLE`.
	//
	// HTTP Mapping: 409 Conflict
	//   "OUT_OF_RANGE" - The operation was attempted past the valid range.
	// E.g., seeking or
	// reading past end-of-file.
	//
	// Unlike `INVALID_ARGUMENT`, this error indicates a problem that may
	// be fixed if the system state changes. For example, a 32-bit
	// file
	// system will generate `INVALID_ARGUMENT` if asked to read at an
	// offset that is not in the range [0,2^32-1], but it will
	// generate
	// `OUT_OF_RANGE` if asked to read from an offset past the current
	// file size.
	//
	// There is a fair bit of overlap between `FAILED_PRECONDITION`
	// and
	// `OUT_OF_RANGE`.  We recommend using `OUT_OF_RANGE` (the more
	// specific
	// error) when it applies so that callers who are iterating through
	// a space can easily look for an `OUT_OF_RANGE` error to detect
	// when
	// they are done.
	//
	// HTTP Mapping: 400 Bad Request
	//   "UNIMPLEMENTED" - The operation is not implemented or is not
	// supported/enabled in this
	// service.
	//
	// HTTP Mapping: 501 Not Implemented
	//   "INTERNAL" - Internal errors.  This means that some invariants
	// expected by the
	// underlying system have been broken.  This error code is reserved
	// for serious errors.
	//
	// HTTP Mapping: 500 Internal Server Error
	//   "UNAVAILABLE" - The service is currently unavailable.  This is most
	// likely a
	// transient condition, which can be corrected by retrying with
	// a backoff. Note that it is not always safe to retry
	// non-idempotent operations.
	//
	// See the guidelines above for deciding between
	// `FAILED_PRECONDITION`,
	// `ABORTED`, and `UNAVAILABLE`.
	//
	// HTTP Mapping: 503 Service Unavailable
	//   "DATA_LOSS" - Unrecoverable data loss or corruption.
	//
	// HTTP Mapping: 500 Internal Server Error
	Code string `json:"code,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Cause") 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. "Cause") 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 *GoogleCloudAssetV1p4beta1AnalysisState) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAssetV1p4beta1AnalysisState
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudAssetV1p4beta1Edge: A directional edge.
type GoogleCloudAssetV1p4beta1Edge struct {
	// SourceNode: The source node of the edge.
	SourceNode string `json:"sourceNode,omitempty"`

	// TargetNode: The target node of the edge.
	TargetNode string `json:"targetNode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SourceNode") 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. "SourceNode") 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 *GoogleCloudAssetV1p4beta1Edge) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAssetV1p4beta1Edge
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudAssetV1p4beta1Identity: An identity under analysis.
type GoogleCloudAssetV1p4beta1Identity struct {
	// AnalysisState: The analysis state of this identity.
	AnalysisState *GoogleCloudAssetV1p4beta1AnalysisState `json:"analysisState,omitempty"`

	// Name: The identity name in any form of members appear in
	// [IAM
	// policy
	// binding](https://cloud.google.com/iam/reference/rest/v1/Binding
	// ), such
	// as:
	// - user:foo@google.com
	// - group:group1@google.com
	// - serviceAccount:s1@prj1.iam.gserviceaccount.com
	// - projectOwner:some_project_id
	// - domain:google.com
	// - allUsers
	// - etc.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalysisState") 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. "AnalysisState") 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 *GoogleCloudAssetV1p4beta1Identity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAssetV1p4beta1Identity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudAssetV1p4beta1IdentityList struct {
	// GroupEdges: Group identity edges of the graph starting from the
	// binding's
	// group members to any node of the identities. The
	// Edge.source_node
	// contains a group, such as "group:parent@google.com".
	// The
	// Edge.target_node contains a member of the group,
	// such as "group:child@google.com" or "user:foo@google.com".
	// This field is present only if the output_group_edges option is
	// enabled in
	// request.
	GroupEdges []*GoogleCloudAssetV1p4beta1Edge `json:"groupEdges,omitempty"`

	// Identities: Only the identities that match one of the following
	// conditions will be
	// presented:
	// - The identity_selector, if it is specified in request;
	// - Otherwise, identities reachable from the policy binding's members.
	Identities []*GoogleCloudAssetV1p4beta1Identity `json:"identities,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GroupEdges") 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. "GroupEdges") 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 *GoogleCloudAssetV1p4beta1IdentityList) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAssetV1p4beta1IdentityList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudAssetV1p4beta1Resource: A Google Cloud resource under
// analysis.
type GoogleCloudAssetV1p4beta1Resource struct {
	// AnalysisState: The analysis state of this resource.
	AnalysisState *GoogleCloudAssetV1p4beta1AnalysisState `json:"analysisState,omitempty"`

	// FullResourceName: The [full
	// resource
	// name](https://cloud.google.com/asset-inventory/docs/resource-
	// name-format)
	FullResourceName string `json:"fullResourceName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalysisState") 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. "AnalysisState") 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 *GoogleCloudAssetV1p4beta1Resource) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudAssetV1p4beta1Resource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IamPolicyAnalysis: An analysis message to group the query and
// results.
type IamPolicyAnalysis struct {
	// AnalysisQuery: The analysis query.
	AnalysisQuery *IamPolicyAnalysisQuery `json:"analysisQuery,omitempty"`

	// AnalysisResults: A list of IamPolicyAnalysisResult that matches the
	// analysis query, or
	// empty if no result is found.
	AnalysisResults []*IamPolicyAnalysisResult `json:"analysisResults,omitempty"`

	// FullyExplored: Represents whether all entries in the analysis_results
	// have been
	// fully explored to answer the query.
	FullyExplored bool `json:"fullyExplored,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnalysisQuery") 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. "AnalysisQuery") 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 *IamPolicyAnalysis) MarshalJSON() ([]byte, error) {
	type NoMethod IamPolicyAnalysis
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IamPolicyAnalysisOutputConfig: Output configuration for export IAM
// policy analysis destination.
type IamPolicyAnalysisOutputConfig struct {
	// GcsDestination: Destination on Cloud Storage.
	GcsDestination *GcsDestination `json:"gcsDestination,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GcsDestination") 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. "GcsDestination") 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 *IamPolicyAnalysisOutputConfig) MarshalJSON() ([]byte, error) {
	type NoMethod IamPolicyAnalysisOutputConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IamPolicyAnalysisQuery: IAM policy analysis query message.
type IamPolicyAnalysisQuery struct {
	// AccessSelector: Optional. Specifies roles or permissions for
	// analysis. This is optional.
	AccessSelector *AccessSelector `json:"accessSelector,omitempty"`

	// IdentitySelector: Optional. Specifies an identity for analysis.
	// Either ResourceSelector or
	// IdentitySelector must be specified.
	IdentitySelector *IdentitySelector `json:"identitySelector,omitempty"`

	// Parent: Required. The relative name of the root asset. Only resources
	// and IAM policies within
	// the parent will be analyzed. This can only be an organization number
	// (such
	// as "organizations/123") or a folder number (such as
	// "folders/123").
	//
	// To know how to get organization id, visit
	// [here
	// ](https://cloud.google.com/resource-manager/docs/creating-managi
	// ng-organization#retrieving_your_organization_id).
	//
	// To know how to get folder id, visit
	// [here
	// ](https://cloud.google.com/resource-manager/docs/creating-managi
	// ng-folders#viewing_or_listing_folders_and_projects).
	Parent string `json:"parent,omitempty"`

	// ResourceSelector: Optional. Specifies a resource for analysis. Either
	// ResourceSelector or
	// IdentitySelector must be specified.
	ResourceSelector *ResourceSelector `json:"resourceSelector,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccessSelector") 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. "AccessSelector") 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 *IamPolicyAnalysisQuery) MarshalJSON() ([]byte, error) {
	type NoMethod IamPolicyAnalysisQuery
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IamPolicyAnalysisResult: IAM Policy analysis result, consisting of
// one IAM policy binding and derived
// access control lists.
type IamPolicyAnalysisResult struct {
	// AccessControlLists: The access control lists derived from the
	// iam_binding that match or
	// potentially match resource and access selectors specified in the
	// request.
	AccessControlLists []*GoogleCloudAssetV1p4beta1AccessControlList `json:"accessControlLists,omitempty"`

	// AttachedResourceFullName: The [full
	// resource
	// name](https://cloud.google.com/asset-inventory/docs/resource-
	// name-format)
	// of the resource to which the iam_binding policy attaches.
	AttachedResourceFullName string `json:"attachedResourceFullName,omitempty"`

	// FullyExplored: Represents whether all analyses on the iam_binding
	// have successfully
	// finished.
	FullyExplored bool `json:"fullyExplored,omitempty"`

	// IamBinding: The Cloud IAM policy binding under analysis.
	IamBinding *Binding `json:"iamBinding,omitempty"`

	// IdentityList: The identity list derived from members of the
	// iam_binding that match or
	// potentially match identity selector specified in the request.
	IdentityList *GoogleCloudAssetV1p4beta1IdentityList `json:"identityList,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccessControlLists")
	// 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. "AccessControlLists") 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 *IamPolicyAnalysisResult) MarshalJSON() ([]byte, error) {
	type NoMethod IamPolicyAnalysisResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IdentitySelector: Specifies an identity for which to determine
// resource access, based on
// roles assigned either directly to them or to the groups they belong
// to,
// directly or indirectly.
type IdentitySelector struct {
	// Identity: Required. The identity appear in the form of members
	// in
	// [IAM
	// policy
	// binding](https://cloud.google.com/iam/reference/rest/v1/Binding
	// ).
	//
	// The examples of supported forms
	// are:
	// "user:mike@example.com",
	// "group:admins@example.com",
	// "domain:goog
	// le.com",
	// "serviceAccount:my-project-id@appspot.gserviceaccount.com".
	//
	//
	// Notice that wildcard characters (such as * and ?) are not
	// supported.
	// You must give a specific identity.
	Identity string `json:"identity,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Identity") 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. "Identity") 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 *IdentitySelector) MarshalJSON() ([]byte, error) {
	type NoMethod IdentitySelector
	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)
}

// Options: Contains request options.
type Options struct {
	// AnalyzeServiceAccountImpersonation: Optional. If true, the response
	// will include access analysis from identities to
	// resources via service account impersonation. This is a very
	// expensive
	// operation, because many derived queries will be executed.
	//
	// For example, if the request analyzes for which resources user A
	// has
	// permission P, and there's an IAM policy states user A
	// has
	// iam.serviceAccounts.getAccessToken permission to a service account
	// SA,
	// and there's another IAM policy states service account SA has
	// permission P
	// to a GCP folder F, then user A potentially has access to the GCP
	// folder
	// F. And those advanced analysis results will be included
	// in
	// AnalyzeIamPolicyResponse.service_account_impersonation_analysis.
	//
	// A
	// nother example, if the request analyzes for who has
	// permission P to a GCP folder F, and there's an IAM policy states user
	// A
	// has iam.serviceAccounts.actAs permission to a service account SA,
	// and
	// there's another IAM policy states service account SA has permission P
	// to
	// the GCP folder F, then user A potentially has access to the GCP
	// folder
	// F. And those advanced analysis results will be included
	// in
	// AnalyzeIamPolicyResponse.service_account_impersonation_analysis.
	//
	// D
	// efault is false.
	AnalyzeServiceAccountImpersonation bool `json:"analyzeServiceAccountImpersonation,omitempty"`

	// ExpandGroups: Optional. If true, the identities section of the result
	// will expand any
	// Google groups appearing in an IAM policy binding.
	//
	// If identity_selector is specified, the identity in the result will
	// be determined by the selector, and this flag will have no
	// effect.
	//
	// Default is false.
	ExpandGroups bool `json:"expandGroups,omitempty"`

	// ExpandResources: Optional. If true, the resource section of the
	// result will expand any
	// resource attached to an IAM policy to include resources lower in
	// the
	// resource hierarchy.
	//
	// For example, if the request analyzes for which resources user A
	// has
	// permission P, and the results include an IAM policy with P on a
	// GCP
	// folder, the results will also include resources in that folder
	// with
	// permission P.
	//
	// If resource_selector is specified, the resource section of the
	// result
	// will be determined by the selector, and this flag will have no
	// effect.
	// Default is false.
	ExpandResources bool `json:"expandResources,omitempty"`

	// ExpandRoles: Optional. If true, the access section of result will
	// expand any roles
	// appearing in IAM policy bindings to include their permissions.
	//
	// If access_selector is specified, the access section of the
	// result
	// will be determined by the selector, and this flag will have no
	// effect.
	//
	// Default is false.
	ExpandRoles bool `json:"expandRoles,omitempty"`

	// OutputGroupEdges: Optional. If true, the result will output group
	// identity edges, starting
	// from the binding's group members, to any expanded identities.
	// Default is false.
	OutputGroupEdges bool `json:"outputGroupEdges,omitempty"`

	// OutputResourceEdges: Optional. If true, the result will output
	// resource edges, starting
	// from the policy attached resource, to any expanded resources.
	// Default is false.
	OutputResourceEdges bool `json:"outputResourceEdges,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AnalyzeServiceAccountImpersonation") 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.
	// "AnalyzeServiceAccountImpersonation") 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 *Options) MarshalJSON() ([]byte, error) {
	type NoMethod Options
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourceSelector: Specifies the resource to analyze for access
// policies, which may be set
// directly on the resource, or on ancestors such as organizations,
// folders or
// projects.
type ResourceSelector struct {
	// FullResourceName: Required. The [full
	// resource
	// name](https://cloud.google.com/asset-inventory/docs/resource-
	// name-format)
	// of a resource of [supported
	// resource
	// types](https://cloud.google.com/asset-inventory/docs/supporte
	// d-asset-types#analyzable_asset_types).
	FullResourceName string `json:"fullResourceName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FullResourceName") 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. "FullResourceName") 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 *ResourceSelector) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceSelector
	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)
}

// method id "cloudasset.analyzeIamPolicy":

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

// AnalyzeIamPolicy: Analyzes IAM policies to answer which identities
// have what accesses on
// which resources.
func (r *V1p4beta1Service) AnalyzeIamPolicy(parent string) *V1p4beta1AnalyzeIamPolicyCall {
	c := &V1p4beta1AnalyzeIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// AnalysisQueryAccessSelectorPermissions sets the optional parameter
// "analysisQuery.accessSelector.permissions": The permissions to appear
// in result.
func (c *V1p4beta1AnalyzeIamPolicyCall) AnalysisQueryAccessSelectorPermissions(analysisQueryAccessSelectorPermissions ...string) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.SetMulti("analysisQuery.accessSelector.permissions", append([]string{}, analysisQueryAccessSelectorPermissions...))
	return c
}

// AnalysisQueryAccessSelectorRoles sets the optional parameter
// "analysisQuery.accessSelector.roles": The roles to appear in result.
func (c *V1p4beta1AnalyzeIamPolicyCall) AnalysisQueryAccessSelectorRoles(analysisQueryAccessSelectorRoles ...string) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.SetMulti("analysisQuery.accessSelector.roles", append([]string{}, analysisQueryAccessSelectorRoles...))
	return c
}

// AnalysisQueryIdentitySelectorIdentity sets the optional parameter
// "analysisQuery.identitySelector.identity": Required. The identity
// appear in the form of members in
// [IAM
// policy
// binding](https://cloud.google.com/iam/reference/rest/v1/Binding
// ).
//
// The examples of supported forms
// are:
// "user:mike@example.com",
// "group:admins@example.com",
// "domain:goog
// le.com",
// "serviceAccount:my-project-id@appspot.gserviceaccount.com".
//
//
// Notice that wildcard characters (such as * and ?) are not
// supported.
// You must give a specific identity.
func (c *V1p4beta1AnalyzeIamPolicyCall) AnalysisQueryIdentitySelectorIdentity(analysisQueryIdentitySelectorIdentity string) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("analysisQuery.identitySelector.identity", analysisQueryIdentitySelectorIdentity)
	return c
}

// AnalysisQueryResourceSelectorFullResourceName sets the optional
// parameter "analysisQuery.resourceSelector.fullResourceName":
// Required. The [full
// resource
// name](https://cloud.google.com/asset-inventory/docs/resource-
// name-format)
// of a resource of [supported
// resource
// types](https://cloud.google.com/asset-inventory/docs/supporte
// d-asset-types#analyzable_asset_types).
func (c *V1p4beta1AnalyzeIamPolicyCall) AnalysisQueryResourceSelectorFullResourceName(analysisQueryResourceSelectorFullResourceName string) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("analysisQuery.resourceSelector.fullResourceName", analysisQueryResourceSelectorFullResourceName)
	return c
}

// OptionsAnalyzeServiceAccountImpersonation sets the optional parameter
// "options.analyzeServiceAccountImpersonation": If true, the response
// will include access analysis from identities to
// resources via service account impersonation. This is a very
// expensive
// operation, because many derived queries will be executed. We
// highly
// recommend you use AssetService.ExportIamPolicyAnalysis rpc
// instead.
//
// For example, if the request analyzes for which resources user A
// has
// permission P, and there's an IAM policy states user A
// has
// iam.serviceAccounts.getAccessToken permission to a service account
// SA,
// and there's another IAM policy states service account SA has
// permission P
// to a GCP folder F, then user A potentially has access to the GCP
// folder
// F. And those advanced analysis results will be included
// in
// AnalyzeIamPolicyResponse.service_account_impersonation_analysis.
//
// A
// nother example, if the request analyzes for who has
// permission P to a GCP folder F, and there's an IAM policy states user
// A
// has iam.serviceAccounts.actAs permission to a service account SA,
// and
// there's another IAM policy states service account SA has permission P
// to
// the GCP folder F, then user A potentially has access to the GCP
// folder
// F. And those advanced analysis results will be included
// in
// AnalyzeIamPolicyResponse.service_account_impersonation_analysis.
//
// D
// efault is false.
func (c *V1p4beta1AnalyzeIamPolicyCall) OptionsAnalyzeServiceAccountImpersonation(optionsAnalyzeServiceAccountImpersonation bool) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("options.analyzeServiceAccountImpersonation", fmt.Sprint(optionsAnalyzeServiceAccountImpersonation))
	return c
}

// OptionsExecutionTimeout sets the optional parameter
// "options.executionTimeout": Amount of time executable has to
// complete.  See JSON representation
// of
// [Duration](https://developers.google.com/protocol-buffers/docs/prot
// o3#json).
//
// If this field is set with a value less than the RPC deadline, and
// the
// execution of your query hasn't finished in the specified
// execution timeout,  you will get a response with partial
// result.
// Otherwise, your query's execution will continue until the RPC
// deadline.
// If it's not finished until then, you will get a  DEADLINE_EXCEEDED
// error.
//
// Default is empty.
func (c *V1p4beta1AnalyzeIamPolicyCall) OptionsExecutionTimeout(optionsExecutionTimeout string) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("options.executionTimeout", optionsExecutionTimeout)
	return c
}

// OptionsExpandGroups sets the optional parameter
// "options.expandGroups": If true, the identities section of the result
// will expand any
// Google groups appearing in an IAM policy binding.
//
// If identity_selector is specified, the identity in the result will
// be determined by the selector, and this flag will have no
// effect.
//
// Default is false.
func (c *V1p4beta1AnalyzeIamPolicyCall) OptionsExpandGroups(optionsExpandGroups bool) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("options.expandGroups", fmt.Sprint(optionsExpandGroups))
	return c
}

// OptionsExpandResources sets the optional parameter
// "options.expandResources": If true, the resource section of the
// result will expand any
// resource attached to an IAM policy to include resources lower in
// the
// resource hierarchy.
//
// For example, if the request analyzes for which resources user A
// has
// permission P, and the results include an IAM policy with P on a
// GCP
// folder, the results will also include resources in that folder
// with
// permission P.
//
// If resource_selector is specified, the resource section of the
// result
// will be determined by the selector, and this flag will have no
// effect.
// Default is false.
func (c *V1p4beta1AnalyzeIamPolicyCall) OptionsExpandResources(optionsExpandResources bool) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("options.expandResources", fmt.Sprint(optionsExpandResources))
	return c
}

// OptionsExpandRoles sets the optional parameter "options.expandRoles":
// If true, the access section of result will expand any roles
// appearing in IAM policy bindings to include their permissions.
//
// If access_selector is specified, the access section of the
// result
// will be determined by the selector, and this flag will have no
// effect.
//
// Default is false.
func (c *V1p4beta1AnalyzeIamPolicyCall) OptionsExpandRoles(optionsExpandRoles bool) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("options.expandRoles", fmt.Sprint(optionsExpandRoles))
	return c
}

// OptionsOutputGroupEdges sets the optional parameter
// "options.outputGroupEdges": If true, the result will output group
// identity edges, starting
// from the binding's group members, to any expanded identities.
// Default is false.
func (c *V1p4beta1AnalyzeIamPolicyCall) OptionsOutputGroupEdges(optionsOutputGroupEdges bool) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("options.outputGroupEdges", fmt.Sprint(optionsOutputGroupEdges))
	return c
}

// OptionsOutputResourceEdges sets the optional parameter
// "options.outputResourceEdges": If true, the result will output
// resource edges, starting
// from the policy attached resource, to any expanded resources.
// Default is false.
func (c *V1p4beta1AnalyzeIamPolicyCall) OptionsOutputResourceEdges(optionsOutputResourceEdges bool) *V1p4beta1AnalyzeIamPolicyCall {
	c.urlParams_.Set("options.outputResourceEdges", fmt.Sprint(optionsOutputResourceEdges))
	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 *V1p4beta1AnalyzeIamPolicyCall) Fields(s ...googleapi.Field) *V1p4beta1AnalyzeIamPolicyCall {
	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 *V1p4beta1AnalyzeIamPolicyCall) IfNoneMatch(entityTag string) *V1p4beta1AnalyzeIamPolicyCall {
	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 *V1p4beta1AnalyzeIamPolicyCall) Context(ctx context.Context) *V1p4beta1AnalyzeIamPolicyCall {
	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 *V1p4beta1AnalyzeIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1p4beta1AnalyzeIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200714")
	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, "v1p4beta1/{+parent}:analyzeIamPolicy")
	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.analyzeIamPolicy" call.
// Exactly one of *AnalyzeIamPolicyResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *AnalyzeIamPolicyResponse.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 *V1p4beta1AnalyzeIamPolicyCall) Do(opts ...googleapi.CallOption) (*AnalyzeIamPolicyResponse, 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 := &AnalyzeIamPolicyResponse{
		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": "Analyzes IAM policies to answer which identities have what accesses on\nwhich resources.",
	//   "flatPath": "v1p4beta1/{v1p4beta1Id}/{v1p4beta1Id1}:analyzeIamPolicy",
	//   "httpMethod": "GET",
	//   "id": "cloudasset.analyzeIamPolicy",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "analysisQuery.accessSelector.permissions": {
	//       "description": "Optional. The permissions to appear in result.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "analysisQuery.accessSelector.roles": {
	//       "description": "Optional. The roles to appear in result.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "analysisQuery.identitySelector.identity": {
	//       "description": "Required. The identity appear in the form of members in\n[IAM policy\nbinding](https://cloud.google.com/iam/reference/rest/v1/Binding).\n\nThe examples of supported forms are:\n\"user:mike@example.com\",\n\"group:admins@example.com\",\n\"domain:google.com\",\n\"serviceAccount:my-project-id@appspot.gserviceaccount.com\".\n\nNotice that wildcard characters (such as * and ?) are not supported.\nYou must give a specific identity.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "analysisQuery.resourceSelector.fullResourceName": {
	//       "description": "Required. The [full resource\nname](https://cloud.google.com/asset-inventory/docs/resource-name-format)\nof a resource of [supported resource\ntypes](https://cloud.google.com/asset-inventory/docs/supported-asset-types#analyzable_asset_types).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "options.analyzeServiceAccountImpersonation": {
	//       "description": "Optional. If true, the response will include access analysis from identities to\nresources via service account impersonation. This is a very expensive\noperation, because many derived queries will be executed. We highly\nrecommend you use AssetService.ExportIamPolicyAnalysis rpc instead.\n\nFor example, if the request analyzes for which resources user A has\npermission P, and there's an IAM policy states user A has\niam.serviceAccounts.getAccessToken permission to a service account SA,\nand there's another IAM policy states service account SA has permission P\nto a GCP folder F, then user A potentially has access to the GCP folder\nF. And those advanced analysis results will be included in\nAnalyzeIamPolicyResponse.service_account_impersonation_analysis.\n\nAnother example, if the request analyzes for who has\npermission P to a GCP folder F, and there's an IAM policy states user A\nhas iam.serviceAccounts.actAs permission to a service account SA, and\nthere's another IAM policy states service account SA has permission P to\nthe GCP folder F, then user A potentially has access to the GCP folder\nF. And those advanced analysis results will be included in\nAnalyzeIamPolicyResponse.service_account_impersonation_analysis.\n\nDefault is false.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "options.executionTimeout": {
	//       "description": "Optional. Amount of time executable has to complete.  See JSON representation of\n[Duration](https://developers.google.com/protocol-buffers/docs/proto3#json).\n\nIf this field is set with a value less than the RPC deadline, and the\nexecution of your query hasn't finished in the specified\nexecution timeout,  you will get a response with partial result.\nOtherwise, your query's execution will continue until the RPC deadline.\nIf it's not finished until then, you will get a  DEADLINE_EXCEEDED error.\n\nDefault is empty.",
	//       "format": "google-duration",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "options.expandGroups": {
	//       "description": "Optional. If true, the identities section of the result will expand any\nGoogle groups appearing in an IAM policy binding.\n\nIf identity_selector is specified, the identity in the result will\nbe determined by the selector, and this flag will have no effect.\n\nDefault is false.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "options.expandResources": {
	//       "description": "Optional. If true, the resource section of the result will expand any\nresource attached to an IAM policy to include resources lower in the\nresource hierarchy.\n\nFor example, if the request analyzes for which resources user A has\npermission P, and the results include an IAM policy with P on a GCP\nfolder, the results will also include resources in that folder with\npermission P.\n\nIf resource_selector is specified, the resource section of the result\nwill be determined by the selector, and this flag will have no effect.\nDefault is false.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "options.expandRoles": {
	//       "description": "Optional. If true, the access section of result will expand any roles\nappearing in IAM policy bindings to include their permissions.\n\nIf access_selector is specified, the access section of the result\nwill be determined by the selector, and this flag will have no effect.\n\nDefault is false.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "options.outputGroupEdges": {
	//       "description": "Optional. If true, the result will output group identity edges, starting\nfrom the binding's group members, to any expanded identities.\nDefault is false.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "options.outputResourceEdges": {
	//       "description": "Optional. If true, the result will output resource edges, starting\nfrom the policy attached resource, to any expanded resources.\nDefault is false.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. The relative name of the root asset. Only resources and IAM policies within\nthe parent will be analyzed. This can only be an organization number (such\nas \"organizations/123\") or a folder number (such as \"folders/123\").\n\nTo know how to get organization id, visit [here\n](https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id).\n\nTo know how to get folder id, visit [here\n](https://cloud.google.com/resource-manager/docs/creating-managing-folders#viewing_or_listing_folders_and_projects).",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p4beta1/{+parent}:analyzeIamPolicy",
	//   "response": {
	//     "$ref": "AnalyzeIamPolicyResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudasset.exportIamPolicyAnalysis":

type V1p4beta1ExportIamPolicyAnalysisCall struct {
	s                              *Service
	parent                         string
	exportiampolicyanalysisrequest *ExportIamPolicyAnalysisRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// ExportIamPolicyAnalysis: Exports the answers of which identities have
// what accesses on which
// resources to a Google Cloud Storage destination. The output format
// is
// the JSON format that represents a AnalyzeIamPolicyResponse
// in the JSON format.
// This method implements the google.longrunning.Operation, 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.
// The
// metadata contains the request to help callers to map responses to
// requests.
func (r *V1p4beta1Service) ExportIamPolicyAnalysis(parent string, exportiampolicyanalysisrequest *ExportIamPolicyAnalysisRequest) *V1p4beta1ExportIamPolicyAnalysisCall {
	c := &V1p4beta1ExportIamPolicyAnalysisCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.exportiampolicyanalysisrequest = exportiampolicyanalysisrequest
	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 *V1p4beta1ExportIamPolicyAnalysisCall) Fields(s ...googleapi.Field) *V1p4beta1ExportIamPolicyAnalysisCall {
	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 *V1p4beta1ExportIamPolicyAnalysisCall) Context(ctx context.Context) *V1p4beta1ExportIamPolicyAnalysisCall {
	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 *V1p4beta1ExportIamPolicyAnalysisCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1p4beta1ExportIamPolicyAnalysisCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200714")
	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.exportiampolicyanalysisrequest)
	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, "v1p4beta1/{+parent}:exportIamPolicyAnalysis")
	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.exportIamPolicyAnalysis" 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 *V1p4beta1ExportIamPolicyAnalysisCall) 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 the answers of which identities have what accesses on which\nresources to a Google Cloud Storage destination. The output format is\nthe JSON format that represents a AnalyzeIamPolicyResponse\nin the JSON format.\nThis method implements the google.longrunning.Operation, which allows\nyou to keep track of the export. We recommend intervals of at least 2\nseconds with exponential retry to poll the export operation result. The\nmetadata contains the request to help callers to map responses to requests.",
	//   "flatPath": "v1p4beta1/{v1p4beta1Id}/{v1p4beta1Id1}:exportIamPolicyAnalysis",
	//   "httpMethod": "POST",
	//   "id": "cloudasset.exportIamPolicyAnalysis",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The relative name of the root asset. Only resources and IAM policies within\nthe parent will be analyzed. This can only be an organization number (such\nas \"organizations/123\") or a folder number (such as \"folders/123\").\n\nTo know how to get organization id, visit [here\n](https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id).\n\nTo know how to get folder id, visit [here\n](https://cloud.google.com/resource-manager/docs/creating-managing-folders#viewing_or_listing_folders_and_projects).",
	//       "location": "path",
	//       "pattern": "^[^/]+/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p4beta1/{+parent}:exportIamPolicyAnalysis",
	//   "request": {
	//     "$ref": "ExportIamPolicyAnalysisRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
