// 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 websecurityscanner provides access to the Web Security Scanner API.
//
// For product documentation, see: https://cloud.google.com/security-scanner/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/websecurityscanner/v1"
//   ...
//   ctx := context.Background()
//   websecurityscannerService, err := websecurityscanner.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:
//
//   websecurityscannerService, err := websecurityscanner.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, ...)
//   websecurityscannerService, err := websecurityscanner.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package websecurityscanner // import "google.golang.org/api/websecurityscanner/v1"

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

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	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

const apiId = "websecurityscanner:v1"
const apiName = "websecurityscanner"
const apiVersion = "v1"
const basePath = "https://websecurityscanner.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...)
	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.Projects = NewProjectsService(s)
	return s, nil
}

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

	Projects *ProjectsService
}

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

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.ScanConfigs = NewProjectsScanConfigsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	ScanConfigs *ProjectsScanConfigsService
}

func NewProjectsScanConfigsService(s *Service) *ProjectsScanConfigsService {
	rs := &ProjectsScanConfigsService{s: s}
	rs.ScanRuns = NewProjectsScanConfigsScanRunsService(s)
	return rs
}

type ProjectsScanConfigsService struct {
	s *Service

	ScanRuns *ProjectsScanConfigsScanRunsService
}

func NewProjectsScanConfigsScanRunsService(s *Service) *ProjectsScanConfigsScanRunsService {
	rs := &ProjectsScanConfigsScanRunsService{s: s}
	rs.CrawledUrls = NewProjectsScanConfigsScanRunsCrawledUrlsService(s)
	rs.FindingTypeStats = NewProjectsScanConfigsScanRunsFindingTypeStatsService(s)
	rs.Findings = NewProjectsScanConfigsScanRunsFindingsService(s)
	return rs
}

type ProjectsScanConfigsScanRunsService struct {
	s *Service

	CrawledUrls *ProjectsScanConfigsScanRunsCrawledUrlsService

	FindingTypeStats *ProjectsScanConfigsScanRunsFindingTypeStatsService

	Findings *ProjectsScanConfigsScanRunsFindingsService
}

func NewProjectsScanConfigsScanRunsCrawledUrlsService(s *Service) *ProjectsScanConfigsScanRunsCrawledUrlsService {
	rs := &ProjectsScanConfigsScanRunsCrawledUrlsService{s: s}
	return rs
}

type ProjectsScanConfigsScanRunsCrawledUrlsService struct {
	s *Service
}

func NewProjectsScanConfigsScanRunsFindingTypeStatsService(s *Service) *ProjectsScanConfigsScanRunsFindingTypeStatsService {
	rs := &ProjectsScanConfigsScanRunsFindingTypeStatsService{s: s}
	return rs
}

type ProjectsScanConfigsScanRunsFindingTypeStatsService struct {
	s *Service
}

func NewProjectsScanConfigsScanRunsFindingsService(s *Service) *ProjectsScanConfigsScanRunsFindingsService {
	rs := &ProjectsScanConfigsScanRunsFindingsService{s: s}
	return rs
}

type ProjectsScanConfigsScanRunsFindingsService struct {
	s *Service
}

// Authentication: Scan authentication configuration.
type Authentication struct {
	// CustomAccount: Authentication using a custom account.
	CustomAccount *CustomAccount `json:"customAccount,omitempty"`

	// GoogleAccount: Authentication using a Google account.
	GoogleAccount *GoogleAccount `json:"googleAccount,omitempty"`

	// IapCredential: Authentication using Identity-Aware-Proxy (IAP).
	IapCredential *IapCredential `json:"iapCredential,omitempty"`

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

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

// CrawledUrl: A CrawledUrl resource represents a URL that was crawled
// during a ScanRun. Web
// Security Scanner Service crawls the web applications, following all
// links
// within the scope of sites, to find the URLs to test against.
type CrawledUrl struct {
	// Body: Output only. The body of the request that was used to visit the
	// URL.
	Body string `json:"body,omitempty"`

	// HttpMethod: Output only. The http method of the request that was used
	// to visit the URL, in
	// uppercase.
	HttpMethod string `json:"httpMethod,omitempty"`

	// Url: Output only. The URL that was crawled.
	Url string `json:"url,omitempty"`

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

// CustomAccount: Describes authentication configuration that uses a
// custom account.
type CustomAccount struct {
	// LoginUrl: Required. The login form URL of the website.
	LoginUrl string `json:"loginUrl,omitempty"`

	// Password: Required. Input only. The password of the custom account.
	// The credential is stored encrypted
	// and not returned in any response nor included in audit logs.
	Password string `json:"password,omitempty"`

	// Username: Required. The user name of the custom account.
	Username string `json:"username,omitempty"`

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

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

// Finding: A Finding resource represents a vulnerability instance
// identified during a
// ScanRun.
type Finding struct {
	// Body: Output only. The body of the request that triggered the
	// vulnerability.
	Body string `json:"body,omitempty"`

	// Description: Output only. The description of the vulnerability.
	Description string `json:"description,omitempty"`

	// FinalUrl: Output only. The URL where the browser lands when the
	// vulnerability is detected.
	FinalUrl string `json:"finalUrl,omitempty"`

	// FindingType: Output only. The type of the Finding.
	// Detailed and up-to-date information on findings can be found
	// here:
	// https://cloud.google.com/security-scanner/docs/scan-result-detai
	// ls
	FindingType string `json:"findingType,omitempty"`

	// Form: Output only. An addon containing information reported for a
	// vulnerability with an HTML
	// form, if any.
	Form *Form `json:"form,omitempty"`

	// FrameUrl: Output only. If the vulnerability was originated from
	// nested IFrame, the immediate
	// parent IFrame is reported.
	FrameUrl string `json:"frameUrl,omitempty"`

	// FuzzedUrl: Output only. The URL produced by the server-side fuzzer
	// and used in the request that
	// triggered the vulnerability.
	FuzzedUrl string `json:"fuzzedUrl,omitempty"`

	// HttpMethod: Output only. The http method of the request that
	// triggered the vulnerability, in
	// uppercase.
	HttpMethod string `json:"httpMethod,omitempty"`

	// Name: Output only. The resource name of the Finding. The name follows
	// the format
	// of
	// 'projects/{projectId}/scanConfigs/{scanConfigId}/scanruns/{scanRunI
	// d}/findings/{findingId}'.
	// The finding IDs are generated by the system.
	Name string `json:"name,omitempty"`

	// OutdatedLibrary: Output only. An addon containing information about
	// outdated libraries.
	OutdatedLibrary *OutdatedLibrary `json:"outdatedLibrary,omitempty"`

	// ReproductionUrl: Output only. The URL containing human-readable
	// payload that user can leverage to
	// reproduce the vulnerability.
	ReproductionUrl string `json:"reproductionUrl,omitempty"`

	// TrackingId: Output only. The tracking ID uniquely identifies a
	// vulnerability instance across
	// multiple ScanRuns.
	TrackingId string `json:"trackingId,omitempty"`

	// ViolatingResource: Output only. An addon containing detailed
	// information regarding any resource causing the
	// vulnerability such as JavaScript sources, image, audio files, etc.
	ViolatingResource *ViolatingResource `json:"violatingResource,omitempty"`

	// VulnerableHeaders: Output only. An addon containing information about
	// vulnerable or missing HTTP headers.
	VulnerableHeaders *VulnerableHeaders `json:"vulnerableHeaders,omitempty"`

	// VulnerableParameters: Output only. An addon containing information
	// about request parameters which were found
	// to be vulnerable.
	VulnerableParameters *VulnerableParameters `json:"vulnerableParameters,omitempty"`

	// Xss: Output only. An addon containing information reported for an
	// XSS, if any.
	Xss *Xss `json:"xss,omitempty"`

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

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

// FindingTypeStats: A FindingTypeStats resource represents stats
// regarding a specific FindingType
// of Findings under a given ScanRun.
type FindingTypeStats struct {
	// FindingCount: Output only. The count of findings belonging to this
	// finding type.
	FindingCount int64 `json:"findingCount,omitempty"`

	// FindingType: Output only. The finding type associated with the stats.
	FindingType string `json:"findingType,omitempty"`

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

// Form: ! Information about a vulnerability with an HTML.
type Form struct {
	// ActionUri: ! The URI where to send the form when it's submitted.
	ActionUri string `json:"actionUri,omitempty"`

	// Fields: ! The names of form fields related to the vulnerability.
	Fields []string `json:"fields,omitempty"`

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

// GoogleAccount: Describes authentication configuration that uses a
// Google account.
type GoogleAccount struct {
	// Password: Required. Input only. The password of the Google account.
	// The credential is stored encrypted
	// and not returned in any response nor included in audit logs.
	Password string `json:"password,omitempty"`

	// Username: Required. The user name of the Google account.
	Username string `json:"username,omitempty"`

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

// Header: Describes a HTTP Header.
type Header struct {
	// Name: Header name.
	Name string `json:"name,omitempty"`

	// Value: Header value.
	Value string `json:"value,omitempty"`

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

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

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

// IapCredential: Describes authentication configuration for
// Identity-Aware-Proxy (IAP).
type IapCredential struct {
	// IapTestServiceAccountInfo: Authentication configuration when
	// Web-Security-Scanner service
	// account is added in Identity-Aware-Proxy (IAP) access policies.
	IapTestServiceAccountInfo *IapTestServiceAccountInfo `json:"iapTestServiceAccountInfo,omitempty"`

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

// IapTestServiceAccountInfo: Describes authentication configuration
// when Web-Security-Scanner
// service account is added in Identity-Aware-Proxy (IAP) access
// policies.
type IapTestServiceAccountInfo struct {
	// TargetAudienceClientId: Required. Describes OAuth2 client id of
	// resources protected by
	// Identity-Aware-Proxy (IAP).
	TargetAudienceClientId string `json:"targetAudienceClientId,omitempty"`

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

// ListCrawledUrlsResponse: Response for the `ListCrawledUrls` method.
type ListCrawledUrlsResponse struct {
	// CrawledUrls: The list of CrawledUrls returned.
	CrawledUrls []*CrawledUrl `json:"crawledUrls,omitempty"`

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

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

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

// ListFindingTypeStatsResponse: Response for the `ListFindingTypeStats`
// method.
type ListFindingTypeStatsResponse struct {
	// FindingTypeStats: The list of FindingTypeStats returned.
	FindingTypeStats []*FindingTypeStats `json:"findingTypeStats,omitempty"`

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

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

// ListFindingsResponse: Response for the `ListFindings` method.
type ListFindingsResponse struct {
	// Findings: The list of Findings returned.
	Findings []*Finding `json:"findings,omitempty"`

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

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

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

// ListScanConfigsResponse: Response for the `ListScanConfigs` method.
type ListScanConfigsResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no
	// more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ScanConfigs: The list of ScanConfigs returned.
	ScanConfigs []*ScanConfig `json:"scanConfigs,omitempty"`

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

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

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

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

// ListScanRunsResponse: Response for the `ListScanRuns` method.
type ListScanRunsResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no
	// more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ScanRuns: The list of ScanRuns returned.
	ScanRuns []*ScanRun `json:"scanRuns,omitempty"`

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

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

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

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

// OutdatedLibrary: Information reported for an outdated library.
type OutdatedLibrary struct {
	// LearnMoreUrls: URLs to learn more information about the
	// vulnerabilities in the library.
	LearnMoreUrls []string `json:"learnMoreUrls,omitempty"`

	// LibraryName: The name of the outdated library.
	LibraryName string `json:"libraryName,omitempty"`

	// Version: The version number.
	Version string `json:"version,omitempty"`

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

// ScanConfig: A ScanConfig resource contains the configurations to
// launch a scan.
type ScanConfig struct {
	// Authentication: The authentication configuration. If specified,
	// service will use the
	// authentication configuration during scanning.
	Authentication *Authentication `json:"authentication,omitempty"`

	// BlacklistPatterns: The blacklist URL patterns as described
	// in
	// https://cloud.google.com/security-scanner/docs/excluded-urls
	BlacklistPatterns []string `json:"blacklistPatterns,omitempty"`

	// DisplayName: Required. The user provided display name of the
	// ScanConfig.
	DisplayName string `json:"displayName,omitempty"`

	// ExportToSecurityCommandCenter: Controls export of scan configurations
	// and results to Cloud Security
	// Command Center.
	//
	// Possible values:
	//   "EXPORT_TO_SECURITY_COMMAND_CENTER_UNSPECIFIED" - Use default,
	// which is ENABLED.
	//   "ENABLED" - Export results of this scan to Cloud Security Command
	// Center.
	//   "DISABLED" - Do not export results of this scan to Cloud Security
	// Command Center.
	ExportToSecurityCommandCenter string `json:"exportToSecurityCommandCenter,omitempty"`

	// ManagedScan: Whether the scan config is managed by Cloud Web Security
	// Scanner, output
	// only.
	ManagedScan bool `json:"managedScan,omitempty"`

	// MaxQps: The maximum QPS during scanning. A valid value ranges from 5
	// to 20
	// inclusively. If the field is unspecified or its value is set 0,
	// server will
	// default to 15. Other values outside of [5, 20] range will be rejected
	// with
	// INVALID_ARGUMENT error.
	MaxQps int64 `json:"maxQps,omitempty"`

	// Name: The resource name of the ScanConfig. The name follows the
	// format of
	// 'projects/{projectId}/scanConfigs/{scanConfigId}'. The ScanConfig IDs
	// are
	// generated by the system.
	Name string `json:"name,omitempty"`

	// RiskLevel: The risk level selected for the scan
	//
	// Possible values:
	//   "RISK_LEVEL_UNSPECIFIED" - Use default, which is NORMAL.
	//   "NORMAL" - Normal scanning (Recommended)
	//   "LOW" - Lower impact scanning
	RiskLevel string `json:"riskLevel,omitempty"`

	// Schedule: The schedule of the ScanConfig.
	Schedule *Schedule `json:"schedule,omitempty"`

	// StartingUrls: Required. The starting URLs from which the scanner
	// finds site pages.
	StartingUrls []string `json:"startingUrls,omitempty"`

	// StaticIpScan: Whether the scan configuration has enabled static IP
	// address scan feature.
	// If enabled, the scanner will access applications from static IP
	// addresses.
	StaticIpScan bool `json:"staticIpScan,omitempty"`

	// UserAgent: The user agent used during scanning.
	//
	// Possible values:
	//   "USER_AGENT_UNSPECIFIED" - The user agent is unknown. Service will
	// default to CHROME_LINUX.
	//   "CHROME_LINUX" - Chrome on Linux. This is the service default if
	// unspecified.
	//   "CHROME_ANDROID" - Chrome on Android.
	//   "SAFARI_IPHONE" - Safari on IPhone.
	UserAgent string `json:"userAgent,omitempty"`

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

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

// ScanConfigError: Defines a custom error message used by
// CreateScanConfig and UpdateScanConfig
// APIs when scan configuration validation fails. It is also reported as
// part of
// a ScanRunErrorTrace message if scan validation fails due to a
// scan
// configuration error.
type ScanConfigError struct {
	// Code: Output only. Indicates the reason code for a configuration
	// failure.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - There is no error.
	//   "OK" - There is no error.
	//   "INTERNAL_ERROR" - Indicates an internal server error.
	// Please DO NOT USE THIS ERROR CODE unless the root cause is truly
	// unknown.
	//   "APPENGINE_API_BACKEND_ERROR" - One of the seed URLs is an App
	// Engine URL but we cannot validate the scan
	// settings due to an App Engine API backend error.
	//   "APPENGINE_API_NOT_ACCESSIBLE" - One of the seed URLs is an App
	// Engine URL but we cannot access the
	// App Engine API to validate scan settings.
	//   "APPENGINE_DEFAULT_HOST_MISSING" - One of the seed URLs is an App
	// Engine URL but the Default Host of the
	// App Engine is not set.
	//   "CANNOT_USE_GOOGLE_COM_ACCOUNT" - Google corporate accounts can not
	// be used for scanning.
	//   "CANNOT_USE_OWNER_ACCOUNT" - The account of the scan creator can
	// not be used for scanning.
	//   "COMPUTE_API_BACKEND_ERROR" - This scan targets Compute Engine, but
	// we cannot validate scan settings
	// due to a Compute Engine API backend error.
	//   "COMPUTE_API_NOT_ACCESSIBLE" - This scan targets Compute Engine,
	// but we cannot access the Compute Engine
	// API to validate the scan settings.
	//   "CUSTOM_LOGIN_URL_DOES_NOT_BELONG_TO_CURRENT_PROJECT" - The Custom
	// Login URL does not belong to the current project.
	//   "CUSTOM_LOGIN_URL_MALFORMED" - The Custom Login URL is malformed
	// (can not be parsed).
	//   "CUSTOM_LOGIN_URL_MAPPED_TO_NON_ROUTABLE_ADDRESS" - The Custom
	// Login URL is mapped to a non-routable IP address in DNS.
	//   "CUSTOM_LOGIN_URL_MAPPED_TO_UNRESERVED_ADDRESS" - The Custom Login
	// URL is mapped to an IP address which is not reserved for
	// the current project.
	//   "CUSTOM_LOGIN_URL_HAS_NON_ROUTABLE_IP_ADDRESS" - The Custom Login
	// URL has a non-routable IP address.
	//   "CUSTOM_LOGIN_URL_HAS_UNRESERVED_IP_ADDRESS" - The Custom Login URL
	// has an IP address which is not reserved for the
	// current project.
	//   "DUPLICATE_SCAN_NAME" - Another scan with the same name
	// (case-sensitive) already exists.
	//   "INVALID_FIELD_VALUE" - A field is set to an invalid value.
	//   "FAILED_TO_AUTHENTICATE_TO_TARGET" - There was an error trying to
	// authenticate to the scan target.
	//   "FINDING_TYPE_UNSPECIFIED" - Finding type value is not specified in
	// the list findings request.
	//   "FORBIDDEN_TO_SCAN_COMPUTE" - Scan targets Compute Engine, yet
	// current project was not whitelisted for
	// Google Compute Engine Scanning Alpha access.
	//   "FORBIDDEN_UPDATE_TO_MANAGED_SCAN" - User tries to update managed
	// scan
	//   "MALFORMED_FILTER" - The supplied filter is malformed. For example,
	// it can not be parsed, does
	// not have a filter type in expression, or the same filter type
	// appears
	// more than once.
	//   "MALFORMED_RESOURCE_NAME" - The supplied resource name is malformed
	// (can not be parsed).
	//   "PROJECT_INACTIVE" - The current project is not in an active state.
	//   "REQUIRED_FIELD" - A required field is not set.
	//   "RESOURCE_NAME_INCONSISTENT" - Project id, scanconfig id, scanrun
	// id, or finding id are not consistent
	// with each other in resource name.
	//   "SCAN_ALREADY_RUNNING" - The scan being requested to start is
	// already running.
	//   "SCAN_NOT_RUNNING" - The scan that was requested to be stopped is
	// not running.
	//   "SEED_URL_DOES_NOT_BELONG_TO_CURRENT_PROJECT" - One of the seed
	// URLs does not belong to the current project.
	//   "SEED_URL_MALFORMED" - One of the seed URLs is malformed (can not
	// be parsed).
	//   "SEED_URL_MAPPED_TO_NON_ROUTABLE_ADDRESS" - One of the seed URLs is
	// mapped to a non-routable IP address in DNS.
	//   "SEED_URL_MAPPED_TO_UNRESERVED_ADDRESS" - One of the seed URLs is
	// mapped to an IP address which is not reserved
	// for the current project.
	//   "SEED_URL_HAS_NON_ROUTABLE_IP_ADDRESS" - One of the seed URLs has
	// on-routable IP address.
	//   "SEED_URL_HAS_UNRESERVED_IP_ADDRESS" - One of the seed URLs has an
	// IP address that is not reserved
	// for the current project.
	//   "SERVICE_ACCOUNT_NOT_CONFIGURED" - The Cloud Security Scanner
	// service account is not configured under the
	// project.
	//   "TOO_MANY_SCANS" - A project has reached the maximum number of
	// scans.
	//   "UNABLE_TO_RESOLVE_PROJECT_INFO" - Resolving the details of the
	// current project fails.
	//   "UNSUPPORTED_BLACKLIST_PATTERN_FORMAT" - One or more blacklist
	// patterns were in the wrong format.
	//   "UNSUPPORTED_FILTER" - The supplied filter is not supported.
	//   "UNSUPPORTED_FINDING_TYPE" - The supplied finding type is not
	// supported. For example, we do not
	// provide findings of the given finding type.
	//   "UNSUPPORTED_URL_SCHEME" - The URL scheme of one or more of the
	// supplied URLs is not supported.
	Code string `json:"code,omitempty"`

	// FieldName: Output only. Indicates the full name of the ScanConfig
	// field that triggers this error,
	// for example "scan_config.max_qps". This field is provided
	// for
	// troubleshooting purposes only and its actual value can change in
	// the
	// future.
	FieldName string `json:"fieldName,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 *ScanConfigError) MarshalJSON() ([]byte, error) {
	type NoMethod ScanConfigError
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ScanRun: A ScanRun is a output-only resource representing an actual
// run of the scan.
// Next id: 12
type ScanRun struct {
	// EndTime: Output only. The time at which the ScanRun reached
	// termination state - that the ScanRun
	// is either finished or stopped by user.
	EndTime string `json:"endTime,omitempty"`

	// ErrorTrace: Output only. If result_state is an ERROR, this field
	// provides the primary reason for
	// scan's termination and more details, if such are available.
	ErrorTrace *ScanRunErrorTrace `json:"errorTrace,omitempty"`

	// ExecutionState: Output only. The execution state of the ScanRun.
	//
	// Possible values:
	//   "EXECUTION_STATE_UNSPECIFIED" - Represents an invalid state caused
	// by internal server error. This value
	// should never be returned.
	//   "QUEUED" - The scan is waiting in the queue.
	//   "SCANNING" - The scan is in progress.
	//   "FINISHED" - The scan is either finished or stopped by user.
	ExecutionState string `json:"executionState,omitempty"`

	// HasVulnerabilities: Output only. Whether the scan run has found any
	// vulnerabilities.
	HasVulnerabilities bool `json:"hasVulnerabilities,omitempty"`

	// Name: Output only. The resource name of the ScanRun. The name follows
	// the format
	// of
	// 'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunI
	// d}'.
	// The ScanRun IDs are generated by the system.
	Name string `json:"name,omitempty"`

	// ProgressPercent: Output only. The percentage of total completion
	// ranging from 0 to 100.
	// If the scan is in queue, the value is 0.
	// If the scan is running, the value ranges from 0 to 100.
	// If the scan is finished, the value is 100.
	ProgressPercent int64 `json:"progressPercent,omitempty"`

	// ResultState: Output only. The result state of the ScanRun. This field
	// is only available after the
	// execution state reaches "FINISHED".
	//
	// Possible values:
	//   "RESULT_STATE_UNSPECIFIED" - Default value. This value is returned
	// when the ScanRun is not yet
	// finished.
	//   "SUCCESS" - The scan finished without errors.
	//   "ERROR" - The scan finished with errors.
	//   "KILLED" - The scan was terminated by user.
	ResultState string `json:"resultState,omitempty"`

	// StartTime: Output only. The time at which the ScanRun started.
	StartTime string `json:"startTime,omitempty"`

	// UrlsCrawledCount: Output only. The number of URLs crawled during this
	// ScanRun. If the scan is in progress,
	// the value represents the number of URLs crawled up to now.
	UrlsCrawledCount int64 `json:"urlsCrawledCount,omitempty,string"`

	// UrlsTestedCount: Output only. The number of URLs tested during this
	// ScanRun. If the scan is in progress,
	// the value represents the number of URLs tested up to now. The number
	// of
	// URLs tested is usually larger than the number URLS crawled
	// because
	// typically a crawled URL is tested with multiple test payloads.
	UrlsTestedCount int64 `json:"urlsTestedCount,omitempty,string"`

	// WarningTraces: Output only. A list of warnings, if such are
	// encountered during this scan run.
	WarningTraces []*ScanRunWarningTrace `json:"warningTraces,omitempty"`

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

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

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

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

// ScanRunErrorTrace: Output only.
// Defines an error trace message for a ScanRun.
type ScanRunErrorTrace struct {
	// Code: Output only. Indicates the error reason code.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Default value is never used.
	//   "INTERNAL_ERROR" - Indicates that the scan run failed due to an
	// internal server error.
	//   "SCAN_CONFIG_ISSUE" - Indicates a scan configuration error, usually
	// due to outdated ScanConfig
	// settings, such as starting_urls or the DNS configuration.
	//   "AUTHENTICATION_CONFIG_ISSUE" - Indicates an authentication error,
	// usually due to outdated ScanConfig
	// authentication settings.
	//   "TIMED_OUT_WHILE_SCANNING" - Indicates a scan operation timeout,
	// usually caused by a very large site.
	//   "TOO_MANY_REDIRECTS" - Indicates that a scan encountered excessive
	// redirects, either to
	// authentication or some other page outside of the scan scope.
	//   "TOO_MANY_HTTP_ERRORS" - Indicates that a scan encountered numerous
	// errors from the web site
	// pages. When available, most_common_http_error_code field indicates
	// the
	// most common HTTP error code encountered during the scan.
	Code string `json:"code,omitempty"`

	// MostCommonHttpErrorCode: Output only. If the scan encounters
	// TOO_MANY_HTTP_ERRORS, this field indicates the most
	// common HTTP error code, if such is available. For example, if this
	// code is
	// 404, the scan has encountered too many NOT_FOUND responses.
	MostCommonHttpErrorCode int64 `json:"mostCommonHttpErrorCode,omitempty"`

	// ScanConfigError: Output only. If the scan encounters
	// SCAN_CONFIG_ISSUE error, this field has the error
	// message encountered during scan configuration validation that is
	// performed
	// before each scan run.
	ScanConfigError *ScanConfigError `json:"scanConfigError,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 *ScanRunErrorTrace) MarshalJSON() ([]byte, error) {
	type NoMethod ScanRunErrorTrace
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ScanRunWarningTrace: Output only.
// Defines a warning trace message for ScanRun. Warning traces provide
// customers
// with useful information that helps make the scanning process more
// effective.
type ScanRunWarningTrace struct {
	// Code: Output only. Indicates the warning code.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Default value is never used.
	//   "INSUFFICIENT_CRAWL_RESULTS" - Indicates that a scan discovered an
	// unexpectedly low number of URLs. This
	// is sometimes caused by complex navigation features or by using a
	// single
	// URL for numerous pages.
	//   "TOO_MANY_CRAWL_RESULTS" - Indicates that a scan discovered too
	// many URLs to test, or excessive
	// redundant URLs.
	//   "TOO_MANY_FUZZ_TASKS" - Indicates that too many tests have been
	// generated for the scan. Customer
	// should try reducing the number of starting URLs, increasing the QPS
	// rate,
	// or narrowing down the scope of the scan using the excluded patterns.
	//   "BLOCKED_BY_IAP" - Indicates that a scan is blocked by IAP.
	Code string `json:"code,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 *ScanRunWarningTrace) MarshalJSON() ([]byte, error) {
	type NoMethod ScanRunWarningTrace
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Schedule: Scan schedule configuration.
type Schedule struct {
	// IntervalDurationDays: Required. The duration of time between
	// executions in days.
	IntervalDurationDays int64 `json:"intervalDurationDays,omitempty"`

	// ScheduleTime: A timestamp indicates when the next run will be
	// scheduled. The value is
	// refreshed by the server after each run. If unspecified, it will
	// default
	// to current server time, which means the scan will be scheduled to
	// start
	// immediately.
	ScheduleTime string `json:"scheduleTime,omitempty"`

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

// StartScanRunRequest: Request for the `StartScanRun` method.
type StartScanRunRequest struct {
}

// StopScanRunRequest: Request for the `StopScanRun` method.
type StopScanRunRequest struct {
}

// ViolatingResource: Information regarding any resource causing the
// vulnerability such
// as JavaScript sources, image, audio files, etc.
type ViolatingResource struct {
	// ContentType: The MIME type of this resource.
	ContentType string `json:"contentType,omitempty"`

	// ResourceUrl: URL of this violating resource.
	ResourceUrl string `json:"resourceUrl,omitempty"`

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

// VulnerableHeaders: Information about vulnerable or missing HTTP
// Headers.
type VulnerableHeaders struct {
	// Headers: List of vulnerable headers.
	Headers []*Header `json:"headers,omitempty"`

	// MissingHeaders: List of missing headers.
	MissingHeaders []*Header `json:"missingHeaders,omitempty"`

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

// VulnerableParameters: Information about vulnerable request
// parameters.
type VulnerableParameters struct {
	// ParameterNames: The vulnerable parameter names.
	ParameterNames []string `json:"parameterNames,omitempty"`

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

// Xss: Information reported for an XSS.
type Xss struct {
	// AttackVector: The attack vector of the payload triggering this XSS.
	//
	// Possible values:
	//   "ATTACK_VECTOR_UNSPECIFIED" - Unknown attack vector.
	//   "LOCAL_STORAGE" - The attack comes from fuzzing the browser's
	// localStorage.
	//   "SESSION_STORAGE" - The attack comes from fuzzing the browser's
	// sessionStorage.
	//   "WINDOW_NAME" - The attack comes from fuzzing the window's name
	// property.
	//   "REFERRER" - The attack comes from fuzzing the referrer property.
	//   "FORM_INPUT" - The attack comes from fuzzing an input element.
	//   "COOKIE" - The attack comes from fuzzing the browser's cookies.
	//   "POST_MESSAGE" - The attack comes from hijacking the post messaging
	// mechanism.
	//   "GET_PARAMETERS" - The attack comes from fuzzing parameters in the
	// url.
	//   "URL_FRAGMENT" - The attack comes from fuzzing the fragment in the
	// url.
	//   "HTML_COMMENT" - The attack comes from fuzzing the HTML comments.
	//   "POST_PARAMETERS" - The attack comes from fuzzing the POST
	// parameters.
	//   "PROTOCOL" - The attack comes from fuzzing the protocol.
	//   "STORED_XSS" - The attack comes from the server side and is stored.
	//   "SAME_ORIGIN" - The attack is a Same-Origin Method Execution attack
	// via a GET parameter.
	//   "USER_CONTROLLABLE_URL" - The attack payload is received from a
	// third-party host via a URL that is
	// user-controllable
	AttackVector string `json:"attackVector,omitempty"`

	// ErrorMessage: An error message generated by a javascript breakage.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// StackTraces: Stack traces leading to the point where the XSS
	// occurred.
	StackTraces []string `json:"stackTraces,omitempty"`

	// StoredXssSeedingUrl: The reproduction url for the seeding POST
	// request of a Stored XSS.
	StoredXssSeedingUrl string `json:"storedXssSeedingUrl,omitempty"`

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

// method id "websecurityscanner.projects.scanConfigs.create":

type ProjectsScanConfigsCreateCall struct {
	s          *Service
	parent     string
	scanconfig *ScanConfig
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new ScanConfig.
func (r *ProjectsScanConfigsService) Create(parent string, scanconfig *ScanConfig) *ProjectsScanConfigsCreateCall {
	c := &ProjectsScanConfigsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.scanconfig = scanconfig
	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 *ProjectsScanConfigsCreateCall) Fields(s ...googleapi.Field) *ProjectsScanConfigsCreateCall {
	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 *ProjectsScanConfigsCreateCall) Context(ctx context.Context) *ProjectsScanConfigsCreateCall {
	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 *ProjectsScanConfigsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsScanConfigsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	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.scanconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/scanConfigs")
	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 "websecurityscanner.projects.scanConfigs.create" call.
// Exactly one of *ScanConfig or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ScanConfig.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 *ProjectsScanConfigsCreateCall) Do(opts ...googleapi.CallOption) (*ScanConfig, 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 := &ScanConfig{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new ScanConfig.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs",
	//   "httpMethod": "POST",
	//   "id": "websecurityscanner.projects.scanConfigs.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent resource name where the scan is created, which should be a\nproject resource name in the format 'projects/{projectId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/scanConfigs",
	//   "request": {
	//     "$ref": "ScanConfig"
	//   },
	//   "response": {
	//     "$ref": "ScanConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.delete":

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

// Delete: Deletes an existing ScanConfig and its child resources.
func (r *ProjectsScanConfigsService) Delete(name string) *ProjectsScanConfigsDeleteCall {
	c := &ProjectsScanConfigsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsScanConfigsDeleteCall) Fields(s ...googleapi.Field) *ProjectsScanConfigsDeleteCall {
	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 *ProjectsScanConfigsDeleteCall) Context(ctx context.Context) *ProjectsScanConfigsDeleteCall {
	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 *ProjectsScanConfigsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "websecurityscanner.projects.scanConfigs.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ProjectsScanConfigsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an existing ScanConfig and its child resources.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}",
	//   "httpMethod": "DELETE",
	//   "id": "websecurityscanner.projects.scanConfigs.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the ScanConfig to be deleted. The name follows the\nformat of 'projects/{projectId}/scanConfigs/{scanConfigId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.get":

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

// Get: Gets a ScanConfig.
func (r *ProjectsScanConfigsService) Get(name string) *ProjectsScanConfigsGetCall {
	c := &ProjectsScanConfigsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

// Do executes the "websecurityscanner.projects.scanConfigs.get" call.
// Exactly one of *ScanConfig or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ScanConfig.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 *ProjectsScanConfigsGetCall) Do(opts ...googleapi.CallOption) (*ScanConfig, 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 := &ScanConfig{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a ScanConfig.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the ScanConfig to be returned. The name follows the\nformat of 'projects/{projectId}/scanConfigs/{scanConfigId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "ScanConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.list":

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

// List: Lists ScanConfigs under a given project.
func (r *ProjectsScanConfigsService) List(parent string) *ProjectsScanConfigsListCall {
	c := &ProjectsScanConfigsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of ScanConfigs to return, can be limited by server.
// If not specified or not positive, the implementation will select
// a
// reasonable value.
func (c *ProjectsScanConfigsListCall) PageSize(pageSize int64) *ProjectsScanConfigsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results to be returned. This should be
// a
// `next_page_token` value returned from a previous List request.
// If unspecified, the first page of results is returned.
func (c *ProjectsScanConfigsListCall) PageToken(pageToken string) *ProjectsScanConfigsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *ProjectsScanConfigsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/scanConfigs")
	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 "websecurityscanner.projects.scanConfigs.list" call.
// Exactly one of *ListScanConfigsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListScanConfigsResponse.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 *ProjectsScanConfigsListCall) Do(opts ...googleapi.CallOption) (*ListScanConfigsResponse, 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 := &ListScanConfigsResponse{
		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 ScanConfigs under a given project.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of ScanConfigs to return, can be limited by server.\nIf not specified or not positive, the implementation will select a\nreasonable value.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results to be returned. This should be a\n`next_page_token` value returned from a previous List request.\nIf unspecified, the first page of results is returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource name, which should be a project resource name in the\nformat 'projects/{projectId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/scanConfigs",
	//   "response": {
	//     "$ref": "ListScanConfigsResponse"
	//   },
	//   "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 *ProjectsScanConfigsListCall) Pages(ctx context.Context, f func(*ListScanConfigsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "websecurityscanner.projects.scanConfigs.patch":

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

// Patch: Updates a ScanConfig. This method support partial update of a
// ScanConfig.
func (r *ProjectsScanConfigsService) Patch(name string, scanconfig *ScanConfig) *ProjectsScanConfigsPatchCall {
	c := &ProjectsScanConfigsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.scanconfig = scanconfig
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// update mask applies to the resource. For the `FieldMask`
// definition,
// see
// https://developers.google.com/protocol-buffers/docs/re
// ference/google.protobuf#fieldmask
func (c *ProjectsScanConfigsPatchCall) UpdateMask(updateMask string) *ProjectsScanConfigsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsScanConfigsPatchCall) Fields(s ...googleapi.Field) *ProjectsScanConfigsPatchCall {
	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 *ProjectsScanConfigsPatchCall) Context(ctx context.Context) *ProjectsScanConfigsPatchCall {
	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 *ProjectsScanConfigsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsScanConfigsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	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.scanconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "websecurityscanner.projects.scanConfigs.patch" call.
// Exactly one of *ScanConfig or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ScanConfig.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 *ProjectsScanConfigsPatchCall) Do(opts ...googleapi.CallOption) (*ScanConfig, 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 := &ScanConfig{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a ScanConfig. This method support partial update of a ScanConfig.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}",
	//   "httpMethod": "PATCH",
	//   "id": "websecurityscanner.projects.scanConfigs.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The resource name of the ScanConfig. The name follows the format of\n'projects/{projectId}/scanConfigs/{scanConfigId}'. The ScanConfig IDs are\ngenerated by the system.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The update mask applies to the resource. For the `FieldMask` definition,\nsee\nhttps://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "ScanConfig"
	//   },
	//   "response": {
	//     "$ref": "ScanConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.start":

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

// Start: Start a ScanRun according to the given ScanConfig.
func (r *ProjectsScanConfigsService) Start(name string, startscanrunrequest *StartScanRunRequest) *ProjectsScanConfigsStartCall {
	c := &ProjectsScanConfigsStartCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.startscanrunrequest = startscanrunrequest
	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 *ProjectsScanConfigsStartCall) Fields(s ...googleapi.Field) *ProjectsScanConfigsStartCall {
	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 *ProjectsScanConfigsStartCall) Context(ctx context.Context) *ProjectsScanConfigsStartCall {
	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 *ProjectsScanConfigsStartCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsScanConfigsStartCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	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.startscanrunrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:start")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "websecurityscanner.projects.scanConfigs.start" call.
// Exactly one of *ScanRun or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *ScanRun.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 *ProjectsScanConfigsStartCall) Do(opts ...googleapi.CallOption) (*ScanRun, 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 := &ScanRun{
		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": "Start a ScanRun according to the given ScanConfig.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}:start",
	//   "httpMethod": "POST",
	//   "id": "websecurityscanner.projects.scanConfigs.start",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the ScanConfig to be used. The name follows the\nformat of 'projects/{projectId}/scanConfigs/{scanConfigId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:start",
	//   "request": {
	//     "$ref": "StartScanRunRequest"
	//   },
	//   "response": {
	//     "$ref": "ScanRun"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.scanRuns.get":

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

// Get: Gets a ScanRun.
func (r *ProjectsScanConfigsScanRunsService) Get(name string) *ProjectsScanConfigsScanRunsGetCall {
	c := &ProjectsScanConfigsScanRunsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

// Do executes the "websecurityscanner.projects.scanConfigs.scanRuns.get" call.
// Exactly one of *ScanRun or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *ScanRun.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 *ProjectsScanConfigsScanRunsGetCall) Do(opts ...googleapi.CallOption) (*ScanRun, 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 := &ScanRun{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a ScanRun.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}/scanRuns/{scanRunsId}",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.scanRuns.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the ScanRun to be returned. The name follows the\nformat of\n'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+/scanRuns/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "ScanRun"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.scanRuns.list":

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

// List: Lists ScanRuns under a given ScanConfig, in descending order of
// ScanRun
// stop time.
func (r *ProjectsScanConfigsScanRunsService) List(parent string) *ProjectsScanConfigsScanRunsListCall {
	c := &ProjectsScanConfigsScanRunsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of ScanRuns to return, can be limited by server.
// If not specified or not positive, the implementation will select
// a
// reasonable value.
func (c *ProjectsScanConfigsScanRunsListCall) PageSize(pageSize int64) *ProjectsScanConfigsScanRunsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results to be returned. This should be
// a
// `next_page_token` value returned from a previous List request.
// If unspecified, the first page of results is returned.
func (c *ProjectsScanConfigsScanRunsListCall) PageToken(pageToken string) *ProjectsScanConfigsScanRunsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *ProjectsScanConfigsScanRunsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/scanRuns")
	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 "websecurityscanner.projects.scanConfigs.scanRuns.list" call.
// Exactly one of *ListScanRunsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListScanRunsResponse.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 *ProjectsScanConfigsScanRunsListCall) Do(opts ...googleapi.CallOption) (*ListScanRunsResponse, 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 := &ListScanRunsResponse{
		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 ScanRuns under a given ScanConfig, in descending order of ScanRun\nstop time.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}/scanRuns",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.scanRuns.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of ScanRuns to return, can be limited by server.\nIf not specified or not positive, the implementation will select a\nreasonable value.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results to be returned. This should be a\n`next_page_token` value returned from a previous List request.\nIf unspecified, the first page of results is returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource name, which should be a scan resource name in the\nformat 'projects/{projectId}/scanConfigs/{scanConfigId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/scanRuns",
	//   "response": {
	//     "$ref": "ListScanRunsResponse"
	//   },
	//   "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 *ProjectsScanConfigsScanRunsListCall) Pages(ctx context.Context, f func(*ListScanRunsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "websecurityscanner.projects.scanConfigs.scanRuns.stop":

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

// Stop: Stops a ScanRun. The stopped ScanRun is returned.
func (r *ProjectsScanConfigsScanRunsService) Stop(name string, stopscanrunrequest *StopScanRunRequest) *ProjectsScanConfigsScanRunsStopCall {
	c := &ProjectsScanConfigsScanRunsStopCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.stopscanrunrequest = stopscanrunrequest
	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 *ProjectsScanConfigsScanRunsStopCall) Fields(s ...googleapi.Field) *ProjectsScanConfigsScanRunsStopCall {
	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 *ProjectsScanConfigsScanRunsStopCall) Context(ctx context.Context) *ProjectsScanConfigsScanRunsStopCall {
	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 *ProjectsScanConfigsScanRunsStopCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsScanConfigsScanRunsStopCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	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.stopscanrunrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:stop")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "websecurityscanner.projects.scanConfigs.scanRuns.stop" call.
// Exactly one of *ScanRun or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *ScanRun.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 *ProjectsScanConfigsScanRunsStopCall) Do(opts ...googleapi.CallOption) (*ScanRun, 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 := &ScanRun{
		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": "Stops a ScanRun. The stopped ScanRun is returned.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}/scanRuns/{scanRunsId}:stop",
	//   "httpMethod": "POST",
	//   "id": "websecurityscanner.projects.scanConfigs.scanRuns.stop",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the ScanRun to be stopped. The name follows the\nformat of\n'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+/scanRuns/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:stop",
	//   "request": {
	//     "$ref": "StopScanRunRequest"
	//   },
	//   "response": {
	//     "$ref": "ScanRun"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.scanRuns.crawledUrls.list":

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

// List: List CrawledUrls under a given ScanRun.
func (r *ProjectsScanConfigsScanRunsCrawledUrlsService) List(parent string) *ProjectsScanConfigsScanRunsCrawledUrlsListCall {
	c := &ProjectsScanConfigsScanRunsCrawledUrlsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of CrawledUrls to return, can be limited by server.
// If not specified or not positive, the implementation will select
// a
// reasonable value.
func (c *ProjectsScanConfigsScanRunsCrawledUrlsListCall) PageSize(pageSize int64) *ProjectsScanConfigsScanRunsCrawledUrlsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results to be returned. This should be
// a
// `next_page_token` value returned from a previous List request.
// If unspecified, the first page of results is returned.
func (c *ProjectsScanConfigsScanRunsCrawledUrlsListCall) PageToken(pageToken string) *ProjectsScanConfigsScanRunsCrawledUrlsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *ProjectsScanConfigsScanRunsCrawledUrlsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/crawledUrls")
	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 "websecurityscanner.projects.scanConfigs.scanRuns.crawledUrls.list" call.
// Exactly one of *ListCrawledUrlsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListCrawledUrlsResponse.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 *ProjectsScanConfigsScanRunsCrawledUrlsListCall) Do(opts ...googleapi.CallOption) (*ListCrawledUrlsResponse, 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 := &ListCrawledUrlsResponse{
		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": "List CrawledUrls under a given ScanRun.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}/scanRuns/{scanRunsId}/crawledUrls",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.scanRuns.crawledUrls.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of CrawledUrls to return, can be limited by server.\nIf not specified or not positive, the implementation will select a\nreasonable value.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results to be returned. This should be a\n`next_page_token` value returned from a previous List request.\nIf unspecified, the first page of results is returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource name, which should be a scan run resource name in the\nformat\n'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+/scanRuns/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/crawledUrls",
	//   "response": {
	//     "$ref": "ListCrawledUrlsResponse"
	//   },
	//   "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 *ProjectsScanConfigsScanRunsCrawledUrlsListCall) Pages(ctx context.Context, f func(*ListCrawledUrlsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "websecurityscanner.projects.scanConfigs.scanRuns.findingTypeStats.list":

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

// List: List all FindingTypeStats under a given ScanRun.
func (r *ProjectsScanConfigsScanRunsFindingTypeStatsService) List(parent string) *ProjectsScanConfigsScanRunsFindingTypeStatsListCall {
	c := &ProjectsScanConfigsScanRunsFindingTypeStatsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

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

func (c *ProjectsScanConfigsScanRunsFindingTypeStatsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/findingTypeStats")
	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 "websecurityscanner.projects.scanConfigs.scanRuns.findingTypeStats.list" call.
// Exactly one of *ListFindingTypeStatsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListFindingTypeStatsResponse.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 *ProjectsScanConfigsScanRunsFindingTypeStatsListCall) Do(opts ...googleapi.CallOption) (*ListFindingTypeStatsResponse, 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 := &ListFindingTypeStatsResponse{
		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": "List all FindingTypeStats under a given ScanRun.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}/scanRuns/{scanRunsId}/findingTypeStats",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.scanRuns.findingTypeStats.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent resource name, which should be a scan run resource name in the\nformat\n'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+/scanRuns/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/findingTypeStats",
	//   "response": {
	//     "$ref": "ListFindingTypeStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.scanRuns.findings.get":

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

// Get: Gets a Finding.
func (r *ProjectsScanConfigsScanRunsFindingsService) Get(name string) *ProjectsScanConfigsScanRunsFindingsGetCall {
	c := &ProjectsScanConfigsScanRunsFindingsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

// Do executes the "websecurityscanner.projects.scanConfigs.scanRuns.findings.get" call.
// Exactly one of *Finding or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Finding.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 *ProjectsScanConfigsScanRunsFindingsGetCall) Do(opts ...googleapi.CallOption) (*Finding, 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 := &Finding{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a Finding.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}/scanRuns/{scanRunsId}/findings/{findingsId}",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.scanRuns.findings.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the Finding to be returned. The name follows the\nformat of\n'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}/findings/{findingId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+/scanRuns/[^/]+/findings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Finding"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "websecurityscanner.projects.scanConfigs.scanRuns.findings.list":

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

// List: List Findings under a given ScanRun.
func (r *ProjectsScanConfigsScanRunsFindingsService) List(parent string) *ProjectsScanConfigsScanRunsFindingsListCall {
	c := &ProjectsScanConfigsScanRunsFindingsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": The filter expression.
// The expression must be in the format: <field>
// <operator> <value>.
// Supported field: 'finding_type'.
// Supported operator: '='.
func (c *ProjectsScanConfigsScanRunsFindingsListCall) Filter(filter string) *ProjectsScanConfigsScanRunsFindingsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of Findings to return, can be limited by server.
// If not specified or not positive, the implementation will select
// a
// reasonable value.
func (c *ProjectsScanConfigsScanRunsFindingsListCall) PageSize(pageSize int64) *ProjectsScanConfigsScanRunsFindingsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results to be returned. This should be
// a
// `next_page_token` value returned from a previous List request.
// If unspecified, the first page of results is returned.
func (c *ProjectsScanConfigsScanRunsFindingsListCall) PageToken(pageToken string) *ProjectsScanConfigsScanRunsFindingsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *ProjectsScanConfigsScanRunsFindingsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200108")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/findings")
	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 "websecurityscanner.projects.scanConfigs.scanRuns.findings.list" call.
// Exactly one of *ListFindingsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListFindingsResponse.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 *ProjectsScanConfigsScanRunsFindingsListCall) Do(opts ...googleapi.CallOption) (*ListFindingsResponse, 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 := &ListFindingsResponse{
		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": "List Findings under a given ScanRun.",
	//   "flatPath": "v1/projects/{projectsId}/scanConfigs/{scanConfigsId}/scanRuns/{scanRunsId}/findings",
	//   "httpMethod": "GET",
	//   "id": "websecurityscanner.projects.scanConfigs.scanRuns.findings.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The filter expression. The expression must be in the format: \u003cfield\u003e\n\u003coperator\u003e \u003cvalue\u003e.\nSupported field: 'finding_type'.\nSupported operator: '='.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of Findings to return, can be limited by server.\nIf not specified or not positive, the implementation will select a\nreasonable value.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results to be returned. This should be a\n`next_page_token` value returned from a previous List request.\nIf unspecified, the first page of results is returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource name, which should be a scan run resource name in the\nformat\n'projects/{projectId}/scanConfigs/{scanConfigId}/scanRuns/{scanRunId}'.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/scanConfigs/[^/]+/scanRuns/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/findings",
	//   "response": {
	//     "$ref": "ListFindingsResponse"
	//   },
	//   "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 *ProjectsScanConfigsScanRunsFindingsListCall) Pages(ctx context.Context, f func(*ListFindingsResponse) 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)
	}
}
